diff --git a/frontend/src/services/i18n/i18n.js b/frontend/src/services/i18n/i18n.js index 7061f6ba6..fd383b1b6 100644 --- a/frontend/src/services/i18n/i18n.js +++ b/frontend/src/services/i18n/i18n.js @@ -1,3 +1,5 @@ +import moment from 'moment'; + /** * I18n * @@ -13,10 +15,15 @@ export class I18n { - translations = {}; + _translations = {}; + _datetimeLocale = undefined; add(id, translation) { - this.translations[id] = translation; + if (!this._translations[id]) { + this._translations[id] = translation; + } else { + throw new Error('I18N Error: Attempting to set translation multiple times for »' + id + '«!'); + } } addMany(manyTranslations) { @@ -24,9 +31,27 @@ export class I18n { } get(id) { - if (!this.translations[id]) { + if (!this._translations[id]) { throw new Error('I18N Error: Translation missing for »' + id + '«!'); } - return this.translations[id]; + return this._translations[id]; + } + + + setDatetimeLocale(locale) { + if (!this._datetimeLocale) { + moment.locale(locale); + this._datetimeLocale = locale; + } else { + throw new Error('I18N Error: Attempting to set datetime locale multiple times!'); + } + } + + getDatetimeLocale() { + if (!this._datetimeLocale) { + throw new Error('I18N Error: Attempting to access datetime locale when it has not been set!'); + } + + return this._datetimeLocale; } } diff --git a/frontend/src/utils/form/datepicker.js b/frontend/src/utils/form/datepicker.js index 2cc4972c8..b8ba0869f 100644 --- a/frontend/src/utils/form/datepicker.js +++ b/frontend/src/utils/form/datepicker.js @@ -48,9 +48,6 @@ const DATEPICKER_CONFIG = { timeMinutes: 0, timeSeconds: 0, - // german settings - // TODO: hardcoded, get from current language / settings - locale: 'de', weekStart: 1, dateFormat: FORM_DATE_FORMAT_DATE_DT, timeFormat: FORM_DATE_FORMAT_TIME_DT, @@ -86,6 +83,7 @@ export class Datepicker { datepickerInstance; _element; elementType; + _locale; constructor(element) { if (!element) { @@ -96,6 +94,8 @@ export class Datepicker { return false; } + this._locale = window.App.i18n.getDatetimeLocale(); + // initialize datepickerCollections singleton if not already done if (!Datepicker.datepickerCollections) { Datepicker.datepickerCollections = new Map(); @@ -134,7 +134,7 @@ export class Datepicker { } // initialize tail.datetime (datepicker) instance and let it do weird stuff with the element value - this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig }); + this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig, locale: this._locale }); // reset date to something sane if (parsedMomentDate) diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index bf651eca0..364fcb8b4 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -2104,3 +2104,9 @@ MenuGlossary: Begriffsverzeichnis Applicant: Bewerber CourseParticipant: Kursteilnehmer +Administrator: Administrator +CsvFormat: CSV-Format +ExerciseSheet: Übungsblatt +DefinitionCourseEvents: Kurstermine +DefinitionCourseNews: Kurs-Aktuelles +Invitations: Einladungen \ No newline at end of file diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index f3a46e755..ce14e2845 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -1802,7 +1802,7 @@ ApplicationRatingSection: Grading ApplicationRatingSectionSelfTip: You are authorised to edit the application as well as it's grading. AllocationSchoolShort: Department -Allocation: Central alloction +Allocation: Central allocation AllocationRegisterTo: Registration until AllocationListTitle: Central allocations @@ -2100,3 +2100,9 @@ MenuGlossary: Glossary Applicant: Applicant CourseParticipant: Course participant +Administrator: Administrator +CsvFormat: CSV format +ExerciseSheet: Exercise sheet +DefinitionCourseEvents: Course occurrences +DefinitionCourseNews: Course news +Invitations: Invitations \ No newline at end of file diff --git a/src/Foundation.hs b/src/Foundation.hs index 34b7d6013..50d2b538d 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -1930,6 +1930,7 @@ siteLayout' headingOverride widget = do let -- See Utils.Frontend.I18n and files in messages/frontend for message definitions frontendI18n = toJSON (mr :: FrontendMessage -> Text) + frontendDatetimeLocale <- toJSON <$> selectLanguage frontendDatetimeLocales pc <- widgetToPageContent $ do -- fonts diff --git a/src/Handler/Info.hs b/src/Handler/Info.hs index c4a5fe7dc..69aa8437b 100644 --- a/src/Handler/Info.hs +++ b/src/Handler/Info.hs @@ -2,6 +2,7 @@ module Handler.Info where import Import import Handler.Utils +import Handler.Info.TH import qualified Data.Map as Map import qualified Data.CaseInsensitive as CI @@ -84,7 +85,4 @@ getGlossaryR = $(widgetFile "glossary") where entries = $(i18nWidgetFiles "glossary") - msgMap = Map.fromList - [ ("applicant" , MsgApplicant ) - , ("course-participant", MsgCourseParticipant) - ] + msgMap = $(glossaryTerms "glossary") diff --git a/src/Handler/Info/TH.hs b/src/Handler/Info/TH.hs new file mode 100644 index 000000000..25c55bdb6 --- /dev/null +++ b/src/Handler/Info/TH.hs @@ -0,0 +1,23 @@ +module Handler.Info.TH + ( glossaryTerms + ) where + +import Import +import Handler.Utils.I18n + +import Language.Haskell.TH + +import qualified Data.Char as Char + +import qualified Data.Map.Strict as Map +import qualified Data.Text as Text + + +glossaryTerms :: FilePath -> Q Exp +glossaryTerms basename = do + translationsAvailable <- i18nWidgetFilesAvailable' basename + let terms = Map.mapWithKey (\k _ -> "Msg" <> unPathPiece k) translationsAvailable + [e|Map.fromList $(listE . map (\(int, msg) -> tupE [litE . stringL $ repack int, conE $ mkName msg]) $ Map.toList terms)|] + where + unPathPiece :: Text -> String + unPathPiece = repack . mconcat . map (over _head Char.toUpper) . Text.splitOn "-" diff --git a/src/Handler/Utils/I18n.hs b/src/Handler/Utils/I18n.hs index f3b2e157a..a98067a49 100644 --- a/src/Handler/Utils/I18n.hs +++ b/src/Handler/Utils/I18n.hs @@ -1,10 +1,13 @@ module Handler.Utils.I18n - where + ( i18nWidgetFile + , i18nWidgetFilesAvailable, i18nWidgetFilesAvailable', i18nWidgetFiles + ) where import Import import Language.Haskell.TH import Language.Haskell.TH.Syntax (qRunIO) +import qualified Language.Haskell.TH.Syntax as TH import qualified Data.List as List import qualified Data.List.NonEmpty as NonEmpty @@ -47,8 +50,8 @@ i18nWidgetFile basename = do ] ++ [ 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)|] -i18nWidgetFiles :: FilePath -> Q Exp -i18nWidgetFiles basename = do +i18nWidgetFilesAvailable' :: FilePath -> Q (Map Text (NonEmpty Text)) +i18nWidgetFilesAvailable' basename = do let i18nDirectory = "templates" "i18n" basename availableFiles <- qRunIO $ listDirectory i18nDirectory let fileKinds' = fmap (pack . dropExtension . takeBaseName &&& toTranslation . pack . takeBaseName) availableFiles @@ -58,6 +61,15 @@ i18nWidgetFiles basename = do availableTranslations' <- iforM fileKinds $ \kind -> maybe (fail $ "‘" <> i18nDirectory <> "’ has no translations for ‘" <> unpack kind <> "’") return . NonEmpty.nonEmpty + return availableTranslations' + +i18nWidgetFilesAvailable :: FilePath -> Q Exp +i18nWidgetFilesAvailable = TH.lift <=< i18nWidgetFilesAvailable' + +i18nWidgetFiles :: FilePath -> Q Exp +i18nWidgetFiles basename = do + availableTranslations' <- i18nWidgetFilesAvailable' basename + -- Dispatch to correct language (depending on user settings via `selectLanguage`) at run time ws <- newName "ws" -- Name for dispatch function letE diff --git a/src/Utils/Frontend/I18n.hs b/src/Utils/Frontend/I18n.hs index 9c8533496..1d1c24652 100644 --- a/src/Utils/Frontend/I18n.hs +++ b/src/Utils/Frontend/I18n.hs @@ -1,5 +1,6 @@ module Utils.Frontend.I18n ( FrontendMessage(..) + , frontendDatetimeLocales ) where import ClassyPrelude @@ -14,6 +15,9 @@ import Data.Aeson.Types (toJSONKeyText) import Data.Aeson.TH import qualified Data.Char as Char +import Data.List.NonEmpty (NonEmpty(..)) +import Text.Shakespeare.I18N (Lang) + -- | I18n-Messages used in JavaScript-Frontend -- @@ -39,3 +43,7 @@ instance ToJSONKey FrontendMessage where toJSONKey = toJSONKeyText toPathPiece instance FromJSONKey FrontendMessage where fromJSONKey = FromJSONKeyTextParser $ parseJSON . String + + +frontendDatetimeLocales :: NonEmpty Lang +frontendDatetimeLocales = "de" :| ["en"] diff --git a/src/Utils/Lang.hs b/src/Utils/Lang.hs index fe41e110f..3280c62fc 100644 --- a/src/Utils/Lang.hs +++ b/src/Utils/Lang.hs @@ -11,8 +11,6 @@ import qualified Data.List as List import qualified Data.CaseInsensitive as CI -import Control.Lens (none) - import Yesod.Core.Types (HandlerData(handlerRequest), YesodRequest(reqLangs)) import qualified Network.Wai.Parse as NWP @@ -41,7 +39,7 @@ selectLanguages avL (l:ls) , l'' <- matchesFor l' , langMatches lParts' l'' ] - = let now = nonEmpty . filter (\l' -> none (((==) `on` CI.mk) l') ls) $ sortOn (Down . length) found + = let now = nonEmpty $ sortOn (Down . length) found others = selectLanguages avL ls in maybe id (\now' others' -> NonEmpty.fromList $ toList now' ++ filter (`notElem` toList now') (toList others')) now others | otherwise = selectLanguages avL ls diff --git a/templates/glossary.cassius b/templates/glossary.cassius index 226288fc5..8a6bc42cf 100644 --- a/templates/glossary.cassius +++ b/templates/glossary.cassius @@ -11,4 +11,4 @@ margin-left: 12px dd + dt, .dd + dt, dd + .dt, .dd + .dt - margin-top: 17px \ No newline at end of file + margin-top: 17px diff --git a/templates/i18n.julius b/templates/i18n.julius index 97c088a81..690f8da89 100644 --- a/templates/i18n.julius +++ b/templates/i18n.julius @@ -1,6 +1,6 @@ if (window.App) { window.App.i18n.addMany(#{frontendI18n}); - // window.App.i18n.setLang(lang); TODO: set language string for datepicker config + window.App.i18n.setDatetimeLocale(#{frontendDatetimeLocale}); } else { throw new Error('I18n JavaScript service is missing!'); } diff --git a/templates/i18n/glossary/administrator.de-de-formal.hamlet b/templates/i18n/glossary/administrator.de-de-formal.hamlet new file mode 100644 index 000000000..b811f11f0 --- /dev/null +++ b/templates/i18n/glossary/administrator.de-de-formal.hamlet @@ -0,0 +1,7 @@ +$newline never +
+ Nutzer, die, um die Funktionstüchtigkeit des Systems zu erhalten, über # + erweiterte Rechte innerhalb eines oder mehrerer Institute verfügen.
+ Haben vollen Zugriff auf alle Kurse und Funktionen innerhalb ihrer Institute # + und auf einige systemweite Funktionalitäten wie z.B. das Ausstellen von # + Uni2work-internen Kennungen. diff --git a/templates/i18n/glossary/allocation.de-de-formal.hamlet b/templates/i18n/glossary/allocation.de-de-formal.hamlet new file mode 100644 index 000000000..7f74f9d15 --- /dev/null +++ b/templates/i18n/glossary/allocation.de-de-formal.hamlet @@ -0,0 +1,7 @@ +$newline never +
+ Da verfügbare Kapazitäten in einigen Sorten von Veranstaltung (speziell # + Praktika und Seminare) i.A. nicht hinreichend sind für alle Studierenden die # + in einem bestimmten Semester an einer deartigen Veranstaltung teilnehmen # + wollen oder müssen, werden die verfügbaren Plätze zentral auf die # + Interessenten verteilt. diff --git a/templates/i18n/glossary/corrector.de-de-formal.hamlet b/templates/i18n/glossary/corrector.de-de-formal.hamlet new file mode 100644 index 000000000..6fc4ef37e --- /dev/null +++ b/templates/i18n/glossary/corrector.de-de-formal.hamlet @@ -0,0 +1,4 @@ +$newline never +
+ Nutzer, die von einem Kursverwalter beauftragt wurden bei der Korrektur von # + Übungsblättern und/oder Prüfungen mitzuwirken. diff --git a/templates/i18n/glossary/course-application-required.de-de-formal.hamlet b/templates/i18n/glossary/course-application-required.de-de-formal.hamlet new file mode 100644 index 000000000..a59191f5d --- /dev/null +++ b/templates/i18n/glossary/course-application-required.de-de-formal.hamlet @@ -0,0 +1,14 @@ +$newline never +
+

+ Wenn eine Veranstaltung ein Bewerbungsverfahren hat, werden, statt sich als # + Student direkt für die Veranstaltung anzumelden, nur Bewerbungen an die # + Veranstaltung gestellt.
+ Es ist dann Aufgabe der Kursverwalter die Bewerbungen zu bewerten und ggf. zu # + akzeptieren. +

+ Auch Veranstaltungen, die an einer Zentralanmeldung teilnehmen, können ein # + Bewerbungsverfahren haben oder nicht.
+ In diesem Fall werden immer Bewerbungen (über die Zentralanmeldung) an den # + Kurs gestellt, es werden jedoch die Einstellungen vom kurseigenen # + Bewerbungsverfahren übernommen (z.B. ob die Abgabe von Dateien erlaubt ist). diff --git a/templates/i18n/glossary/course-application-template.de-de-formal.hamlet b/templates/i18n/glossary/course-application-template.de-de-formal.hamlet new file mode 100644 index 000000000..3f5d05417 --- /dev/null +++ b/templates/i18n/glossary/course-application-template.de-de-formal.hamlet @@ -0,0 +1,8 @@ +$newline never +

+ Anmeldungsvorlagen +
+ Wenn eine Veranstaltung ein Bewerbungsverfahren hat, dass die Abgabe von # + Dateien erlaubt, gibt es für Kursverwalter die Möglichkeit einen Satz von # + Dateien zu publizieren der potentiellen Bewerbern dabei helfen soll # + Bewerbungen anzufertigen, die den Erwartungen der Kursverwalter entsprechen. diff --git a/templates/i18n/glossary/course-exams.de-de-formal.hamlet b/templates/i18n/glossary/course-exams.de-de-formal.hamlet new file mode 100644 index 000000000..f6bee2fd3 --- /dev/null +++ b/templates/i18n/glossary/course-exams.de-de-formal.hamlet @@ -0,0 +1,4 @@ +$newline never +
+ Es lassen sich quasi beliebige Prüfungsformen (Projektabnahmen, mündliche # + Prüfungen, Klausuren, ...) in Uni2work modellieren. diff --git a/templates/i18n/glossary/course-lecturers.de-de-formal.hamlet b/templates/i18n/glossary/course-lecturers.de-de-formal.hamlet new file mode 100644 index 000000000..056e49c14 --- /dev/null +++ b/templates/i18n/glossary/course-lecturers.de-de-formal.hamlet @@ -0,0 +1,5 @@ +$newline never +
+ Nutzer die bei der Organisation einer Veranstaltung mitwirken und hierfür vom # + Nutzer, der den Kurs im System angelegt hat, volle Kontrolle über alle Aspekte # + der Veranstaltung erhalten haben. diff --git a/templates/i18n/glossary/course-material.de-de-formal.hamlet b/templates/i18n/glossary/course-material.de-de-formal.hamlet new file mode 100644 index 000000000..671aed67e --- /dev/null +++ b/templates/i18n/glossary/course-material.de-de-formal.hamlet @@ -0,0 +1,5 @@ +$newline never +
+ Kursverwalter haben die Möglichkeit direkt in Uni2work zusätzliche # + Kursunterlagen (z.B. Foliensätze oder Programmbeispiele) an ihre # + Kursteilnehmer zu verteilen. diff --git a/templates/i18n/glossary/csv-format.de-de-formal.hamlet b/templates/i18n/glossary/csv-format.de-de-formal.hamlet new file mode 100644 index 000000000..faa47186d --- /dev/null +++ b/templates/i18n/glossary/csv-format.de-de-formal.hamlet @@ -0,0 +1,12 @@ +$newline never +
+ CSV-Datei +
+ CSV-Import +
+ CSV-Export +
+ Ein weit verbreitetes Format zum semi-strukturierten Datenaustausch zwischen # + unterschiedlichen Systemen.
+ Kann von den meisten gängigen Tabellenkalkulations-Programmen verarbeitet # + werden. diff --git a/templates/i18n/glossary/definition-course-events.de-de-formal.hamlet b/templates/i18n/glossary/definition-course-events.de-de-formal.hamlet new file mode 100644 index 000000000..37bb04205 --- /dev/null +++ b/templates/i18n/glossary/definition-course-events.de-de-formal.hamlet @@ -0,0 +1,5 @@ +$newline never +
+ Kursverwalter haben die Möglichkeit Termine im Bezug auf ihre Veranstaltung # + (Vorlesungen, Zentralübung, Klausureinsicht, ...) direkt auf der Kursseite zu # + publizieren. diff --git a/templates/i18n/glossary/definition-course-news.de-de-formal.hamlet b/templates/i18n/glossary/definition-course-news.de-de-formal.hamlet new file mode 100644 index 000000000..6d65c57b0 --- /dev/null +++ b/templates/i18n/glossary/definition-course-news.de-de-formal.hamlet @@ -0,0 +1,4 @@ +$newline never +
+ Kursverwalter haben die Möglichkeit Neuigkeiten und Ankündigungen im Bezug auf # + ihre Veranstaltung direkt auf der Kursseite zu publizieren. diff --git a/templates/i18n/glossary/exam-result.de-de-formal.hamlet b/templates/i18n/glossary/exam-result.de-de-formal.hamlet new file mode 100644 index 000000000..062047f3a --- /dev/null +++ b/templates/i18n/glossary/exam-result.de-de-formal.hamlet @@ -0,0 +1,8 @@ +$newline never +
+ Kursverwalter (und von ihnen beauftragte Korrektoren) können die Ergebnisse # + einer Prüfung direkt in Uni2work hinterlegen.
+ Dies dient sowohl der Rückmeldung an den jeweiligen Studierenden als auch # + können Prüfungsämter, mit den notwendigen Berechtigungen, die # + Prüfungsleistungen direkt aus Uni2work mit ihren eigenen Verwaltungssystemen # + synchronisieren. diff --git a/templates/i18n/glossary/exercise-sheet.de-de-formal.hamlet b/templates/i18n/glossary/exercise-sheet.de-de-formal.hamlet new file mode 100644 index 000000000..0042e2d65 --- /dev/null +++ b/templates/i18n/glossary/exercise-sheet.de-de-formal.hamlet @@ -0,0 +1,8 @@ +$newline never +
+ Kursverwalter haben die Möglichkeit Übungsaufgaben zu ihren Veranstaltung # + direkt in Uni2work an die Kursteilnehmer zu verteilen.
+ Gewöhnlicherweise haben Kursteilnehmer dann die Möglichkeit ihre erarbeiteten # + Lösungen in Uni2work hochzuladen (oder die Abgabe in einem externen System, # + z.B. auf Papier zu markieren) sodass Korrektor, Feedback und etwaige # + Bonuspunkte ebenfalls direkt in Uni2work verwaltet werden können. diff --git a/templates/i18n/glossary/invitations.de-de-formal.hamlet b/templates/i18n/glossary/invitations.de-de-formal.hamlet new file mode 100644 index 000000000..04c71c41c --- /dev/null +++ b/templates/i18n/glossary/invitations.de-de-formal.hamlet @@ -0,0 +1,13 @@ +$newline never +
+ Es besteht in Uni2work an vielen Stellen die Möglichkeit andere Benutzer in # + einen Prozess mit einzubeziehen (z.B. als Kursverwalter, Korrektor, # + Mitabgebender, ...). # + In solchen Fällen ist die interne Benutzerkennung des gewünschten Benutzers # + (z.B. die Campus Kennung) im Allgemeinen nicht bekannt.
+ Deswegen gibt es gewöhnlicherweise die Möglichkeit eine Einladung an eine # + beliebige E-Mail Adresse zu verschicken. # + Wird eine derartige Einladung vom Empfänger angenommen (hierbei wird der # + korrekte Nutzer dann anhand des Logins des Empfängers identifiziert) wird der # + Nutzer ohne weiteres Zutun des Senders in den gewünschten Prozess # + miteinbezogen. diff --git a/templates/i18n/glossary/navigation-favourites.de-de-formal.hamlet b/templates/i18n/glossary/navigation-favourites.de-de-formal.hamlet new file mode 100644 index 000000000..646df5ae9 --- /dev/null +++ b/templates/i18n/glossary/navigation-favourites.de-de-formal.hamlet @@ -0,0 +1,6 @@ +$newline never +
+ Das System markiert für jeden Nutzer eine gewisse Anzahl von Kursen als von # + besonderem Interesse.
+ Die derart markierten Kurse werden für gewöhnlich in einer Leiste am linken # + Rand des Browserfensters angezeigt. diff --git a/templates/i18n/glossary/school-evaluation.de-de-formal.hamlet b/templates/i18n/glossary/school-evaluation.de-de-formal.hamlet new file mode 100644 index 000000000..19754674e --- /dev/null +++ b/templates/i18n/glossary/school-evaluation.de-de-formal.hamlet @@ -0,0 +1,6 @@ +$newline never +
+ Diese Berechtigung wird einzelnen Benutzern von einem Administrator für ein # + bestimmtes Institut erteilt.
+ Diese Benutzer können dann die Teilnehmerlisten aller Kurse des relevanten # + Instituts einsehen um z.B. Vorlesungsumfragen durchzuführen. diff --git a/templates/i18n/glossary/school-exam-office.de-de-formal.hamlet b/templates/i18n/glossary/school-exam-office.de-de-formal.hamlet new file mode 100644 index 000000000..3f0461dab --- /dev/null +++ b/templates/i18n/glossary/school-exam-office.de-de-formal.hamlet @@ -0,0 +1,11 @@ +$newline never +
+

+ Modelliert jene Stellen der Universität, die Zugriff auf Prüfungsleistungen # + benötigen um sicherzustellen, dass Studienmodalitäten erfüllt und Leistungen # + korrekt anerkannt werden.
+

+ Teil des Prüfungsamts ist eine Berechtigung die einzelnen Benutzern von # + einem Administrator für ein bestimmtes Institut eingeräumt wird.
+ Diese Benutzer haben dann u.A. Zugriff auf alle beim relevanten Institut # + erbrachten und in Uni2work hinterlegten Prüfungsleistungen. diff --git a/templates/i18n/glossary/school-lecturer.de-de-formal.hamlet b/templates/i18n/glossary/school-lecturer.de-de-formal.hamlet new file mode 100644 index 000000000..90f2c92c7 --- /dev/null +++ b/templates/i18n/glossary/school-lecturer.de-de-formal.hamlet @@ -0,0 +1,4 @@ +$newline never +

+ Nutzer denen von einem Administrator das Recht eingeräumt wurde innerhalb # + eines Instituts neue Veranstaltungen anzulegen. diff --git a/templates/i18n/glossary/school.de-de-formal.hamlet b/templates/i18n/glossary/school.de-de-formal.hamlet new file mode 100644 index 000000000..07a479cef --- /dev/null +++ b/templates/i18n/glossary/school.de-de-formal.hamlet @@ -0,0 +1,5 @@ +$newline never +
+ Das System ist in den meisten Aspekten in Institute unterteilt.
+ Kurse haben stets eine Institutszugehörigkeit und die meisten # + Benutzerberechtigungen werden Institutsweise vergeben. diff --git a/templates/i18n/glossary/sheet-pseudonym.de-de-formal.hamlet b/templates/i18n/glossary/sheet-pseudonym.de-de-formal.hamlet new file mode 100644 index 000000000..b98c6c845 --- /dev/null +++ b/templates/i18n/glossary/sheet-pseudonym.de-de-formal.hamlet @@ -0,0 +1,10 @@ +$newline never +
+ Ist die Abgabe für ein Übungsblatt über ein Uni2work-externes System (z.B. auf # + Papier) vorgesehen so können sich Kursteilnehmer auf der Seite des jeweiligen # + Übungsblattes Pseudonyme generieren lassen.
+ Wenn die externe Abgabe mit einem derartigen Pseudonym markiert wird haben # + Korrektoren später die Möglichkeit Abgaben in Uni2work anzulegen die zu den # + externen Abgaben korrespondieren.
+ So kann Feedback und etwaige Bonuspunkte direkt in Uni2work verwaltet werden, # + obwohl die tatsächlich Abgabe extern geschehen ist.