feat(info): start glossary

This commit is contained in:
Gregor Kleen 2019-10-22 17:54:03 +02:00
parent 75677dc171
commit 73b0546db6
9 changed files with 101 additions and 3 deletions

View File

@ -2087,4 +2087,10 @@ FavouritesNotNatural: Anzahl der Favoriten muss eine natürliche Zahl sein!
FavouritesSemestersPlaceholder: Anzahl Semester
FavouritesSemestersNotNatural: Anzahl der Favoriten-Semester muss eine natürliche Zahl sein!
ProfileTitle: Benutzereinstellungen
ProfileTitle: Benutzereinstellungen
GlossaryTitle: Begriffsverzeichnis
MenuGlossary: Begriffsverzeichnis
Applicant: Bewerber
CourseParticipant: Kursteilnehmer

1
routes
View File

@ -63,6 +63,7 @@
/info/lecturer InfoLecturerR GET !lecturer
/info/data DataProtR GET !free
/info/allocation InfoAllocationR GET !free
/info/glossary GlossaryR GET !free
/impressum ImpressumR GET !free
/version VersionR GET !free

View File

@ -2182,7 +2182,9 @@ instance YesodBreadcrumbs UniWorX where
if
| mayList -> i18nCrumb MsgBreadcrumbSystemMessage $ Just MessageListR
| otherwise -> i18nCrumb MsgBreadcrumbSystemMessage $ Just HomeR
breadcrumb (MessageListR) = i18nCrumb MsgMenuMessageList $ Just AdminR
breadcrumb MessageListR = i18nCrumb MsgMenuMessageList $ Just AdminR
breadcrumb GlossaryR = i18nCrumb MsgMenuGlossary $ Just InfoR
-- breadcrumb _ = return ("Uni2work", Nothing) -- Default is no breadcrumb at all
submissionList :: TermId -> CourseShorthand -> SheetName -> UserId -> DB [E.Value SubmissionId]
@ -2480,6 +2482,14 @@ pageActions (InfoR) = [
, menuItemModal = False
, menuItemAccessCallback' = return True
}
, MenuItem
{ menuItemType = PageActionPrime
, menuItemLabel = MsgMenuGlossary
, menuItemIcon = Nothing
, menuItemRoute = SomeRoute GlossaryR
, menuItemModal = False
, menuItemAccessCallback' = return True
}
]
pageActions (VersionR) = [
MenuItem

View File

@ -3,6 +3,9 @@ module Handler.Info where
import Import
import Handler.Utils
import qualified Data.Map as Map
import qualified Data.CaseInsensitive as CI
import Development.GitRev
-- | Versionsgeschichte
@ -67,3 +70,21 @@ getInfoLecturerR =
if currentTime > expiryTime
then mempty
else toWidget [whamlet| ^{iconTooltip tooltipNew (Just IconNew) False} |]
getGlossaryR :: Handler Html
getGlossaryR =
siteLayoutMsg' MsgGlossaryTitle $ do
setTitleI MsgGlossaryTitle
MsgRenderer mr <- getMsgRenderer
let
entries' = sortOn (CI.mk . view _2) $ do
(k, v) <- Map.toList entries
msg <- maybeToList $ Map.lookup k msgMap
return (k, mr msg, v)
$(widgetFile "glossary")
where
entries = $(i18nWidgetFiles "glossary")
msgMap = Map.fromList
[ ("applicant" , MsgApplicant )
, ("course-participant", MsgCourseParticipant)
]

View File

@ -9,6 +9,11 @@ import Language.Haskell.TH.Syntax (qRunIO)
import qualified Data.List as List
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Set as Set
import qualified Data.Map as Map
import qualified Data.Text as Text
import System.Directory (listDirectory)
import System.FilePath.Posix (takeBaseName)
@ -40,4 +45,24 @@ i18nWidgetFile basename = do
[ funD ws $ [ clause [litP $ stringL l] (normalB . widgetFile $ "i18n" </> basename </> l) []
| l <- unpack <$> NonEmpty.toList availableTranslations' -- One function definition for every available language
] ++ [ clause [wildP] (normalB [e| error "selectLanguage returned an invalid translation" |]) [] ] -- Fallback mostly there so compiler does not complain about non-exhaustive pattern match
] [e|selectLanguage availableTranslations' >>= $(varE ws)|]
] [e|selectLanguage availableTranslations' >>= $(varE ws)|]
i18nWidgetFiles :: FilePath -> Q Exp
i18nWidgetFiles basename = do
let i18nDirectory = "templates" </> "i18n" </> basename
availableFiles <- qRunIO $ listDirectory i18nDirectory
let fileKinds' = fmap (pack . dropExtension . takeBaseName &&& toTranslation . pack . takeBaseName) availableFiles
fileKinds :: Map Text [Text]
fileKinds = sortWith (NTop . flip List.elemIndex (NonEmpty.toList appLanguages)) . Set.toList <$> Map.fromListWith Set.union [ (kind, Set.singleton l) | (kind, Just l) <- fileKinds' ]
toTranslation fName = listToMaybe . sortOn length . mapMaybe (flip Text.stripPrefix fName) $ map fst fileKinds'
availableTranslations' <- iforM fileKinds $ \kind -> maybe (fail $ "" <> i18nDirectory <> " has no translations for " <> unpack kind <> "") return . NonEmpty.nonEmpty
-- Dispatch to correct language (depending on user settings via `selectLanguage`) at run time
ws <- newName "ws" -- Name for dispatch function
letE
[ funD ws $ [ clause [litP $ stringL kind, litP $ stringL l] (normalB . widgetFile $ "i18n" </> basename </> kind <.> l) []
| (unpack -> kind, ls) <- Map.toList availableTranslations'
, l <- unpack <$> NonEmpty.toList ls
] ++ [ clause [wildP, wildP] (normalB [e| error "selectLanguage returned an invalid translation" |]) [] ] -- Fallback mostly there so compiler does not complain about non-exhaustive pattern match
] [e|imap (\kind ls -> selectLanguage ls >>= $(varE ws) kind) availableTranslations'|]

View File

@ -0,0 +1,14 @@
.glossary
dt, .dt
font-weight: 600
&.sec
font-style: italic
font-size: 0.9rem
font-weight: 600
color: var(--color-fontsec)
dd, .dd
margin-left: 12px
dd + dt, .dd + dt, dd + .dt, .dd + .dt
margin-top: 17px

View File

@ -0,0 +1,5 @@
$newline never
<dl .glossary>
$forall (term, rTerm, wgt) <- entries'
<dt ##{term}>#{rTerm}
^{wgt}

View File

@ -0,0 +1,8 @@
$newline never
<dt .sec>
Bewerbung
<dt .sec>
Zu einem Kurs bewerben
<dd>
Studierende können eine Bewerbung für einen Kurs hinterlegen.<br />
Wird die Bewerbung akzeptiert (oder der Studierende dem Kurs zugeteilt) wird der Studierende zusätzlich Kursteilnehmer.

View File

@ -0,0 +1,8 @@
$newline never
<dt .sec>
Zu einem Kurs anmelden
<dt .sec>
Von einem Kurs abmelden
<dd>
Studierende, die sich explizit mit einem Kurs assoziiert haben (oder ihm zugeteilt wurden).<br />
Haben Zugriff auf Material und Teile des Kurses (Anmeldungen zu Tutorien, Prüfungen, ...)