From 73b0546db674914ca24e0f69c0c17a309e88fc1e Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 22 Oct 2019 17:54:03 +0200 Subject: [PATCH] feat(info): start glossary --- messages/uniworx/de-de-formal.msg | 8 +++++- routes | 1 + src/Foundation.hs | 12 ++++++++- src/Handler/Info.hs | 21 +++++++++++++++ src/Handler/Utils/I18n.hs | 27 ++++++++++++++++++- templates/glossary.cassius | 14 ++++++++++ templates/glossary.hamlet | 5 ++++ .../glossary/applicant.de-de-formal.hamlet | 8 ++++++ .../course-participant.de-de-formal.hamlet | 8 ++++++ 9 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 templates/glossary.cassius create mode 100644 templates/glossary.hamlet create mode 100644 templates/i18n/glossary/applicant.de-de-formal.hamlet create mode 100644 templates/i18n/glossary/course-participant.de-de-formal.hamlet diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index 7e13cd5d5..a32e40c30 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -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 \ No newline at end of file +ProfileTitle: Benutzereinstellungen + +GlossaryTitle: Begriffsverzeichnis +MenuGlossary: Begriffsverzeichnis + +Applicant: Bewerber +CourseParticipant: Kursteilnehmer \ No newline at end of file diff --git a/routes b/routes index b64e379b5..1c5500267 100644 --- a/routes +++ b/routes @@ -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 diff --git a/src/Foundation.hs b/src/Foundation.hs index 1b17acd0c..ffe945263 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -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 diff --git a/src/Handler/Info.hs b/src/Handler/Info.hs index 751bbe171..c4a5fe7dc 100644 --- a/src/Handler/Info.hs +++ b/src/Handler/Info.hs @@ -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) + ] diff --git a/src/Handler/Utils/I18n.hs b/src/Handler/Utils/I18n.hs index 1119191d2..f3b2e157a 100644 --- a/src/Handler/Utils/I18n.hs +++ b/src/Handler/Utils/I18n.hs @@ -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)|] \ No newline at end of file + ] [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'|] diff --git a/templates/glossary.cassius b/templates/glossary.cassius new file mode 100644 index 000000000..226288fc5 --- /dev/null +++ b/templates/glossary.cassius @@ -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 \ No newline at end of file diff --git a/templates/glossary.hamlet b/templates/glossary.hamlet new file mode 100644 index 000000000..5feaa5dfa --- /dev/null +++ b/templates/glossary.hamlet @@ -0,0 +1,5 @@ +$newline never +
+ $forall (term, rTerm, wgt) <- entries' +
#{rTerm} + ^{wgt} diff --git a/templates/i18n/glossary/applicant.de-de-formal.hamlet b/templates/i18n/glossary/applicant.de-de-formal.hamlet new file mode 100644 index 000000000..700dac30a --- /dev/null +++ b/templates/i18n/glossary/applicant.de-de-formal.hamlet @@ -0,0 +1,8 @@ +$newline never +
+ Bewerbung +
+ Zu einem Kurs bewerben +
+ Studierende können eine Bewerbung für einen Kurs hinterlegen.
+ Wird die Bewerbung akzeptiert (oder der Studierende dem Kurs zugeteilt) wird der Studierende zusätzlich Kursteilnehmer. diff --git a/templates/i18n/glossary/course-participant.de-de-formal.hamlet b/templates/i18n/glossary/course-participant.de-de-formal.hamlet new file mode 100644 index 000000000..5c543e376 --- /dev/null +++ b/templates/i18n/glossary/course-participant.de-de-formal.hamlet @@ -0,0 +1,8 @@ +$newline never +
+ Zu einem Kurs anmelden +
+ Von einem Kurs abmelden +
+ Studierende, die sich explizit mit einem Kurs assoziiert haben (oder ihm zugeteilt wurden).
+ Haben Zugriff auf Material und Teile des Kurses (Anmeldungen zu Tutorien, Prüfungen, ...)