From 98f5ff1f4a38ec3299f390d9abdbc2782707cff8 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 18 Nov 2021 13:11:39 +0000 Subject: [PATCH 01/24] first implementation of new layout --- fet2020/members/views.py | 2 +- fet2020/static/js/alpinejs@3.2.2.js | 2517 + fet2020/static/js/gumshoe@5.1.1.js | 484 + fet2020/static/js/scripts.js | 36 + fet2020/static/js/smooth-scroll@16.1.2.js | 650 + fet2020/static/js/toolkit-screen@1.0.0.js | 34 + fet2020/static/styles.css | 200639 +++++++++++++++ fet2020/templates/authentications/login.html | 46 +- fet2020/templates/base.html | 152 + fet2020/templates/blackboard/index.html | 98 +- .../partials/_show_job_posting.html | 35 +- fet2020/templates/home.html | 166 +- fet2020/templates/layout.html | 25 +- fet2020/templates/members/index.html | 230 +- fet2020/templates/members/jobs_list.html | 21 +- fet2020/templates/members/member.html | 12 +- fet2020/templates/members/members_list.html | 2 - .../templates/members/partials/_member.html | 17 +- .../members/partials/_member_details.html | 85 +- fet2020/templates/posts/index.html | 143 +- .../posts/partials/_article_row.html | 17 +- .../templates/posts/partials/_date_box.html | 14 +- .../posts/partials/_meeting_row.html | 20 +- .../templates/posts/partials/_posts_hero.html | 27 +- .../posts/partials/_posts_hero_compact.html | 22 +- fet2020/templates/posts/show.html | 348 +- 26 files changed, 205328 insertions(+), 514 deletions(-) create mode 100644 fet2020/static/js/alpinejs@3.2.2.js create mode 100644 fet2020/static/js/gumshoe@5.1.1.js create mode 100644 fet2020/static/js/scripts.js create mode 100644 fet2020/static/js/smooth-scroll@16.1.2.js create mode 100644 fet2020/static/js/toolkit-screen@1.0.0.js create mode 100644 fet2020/static/styles.css create mode 100644 fet2020/templates/base.html diff --git a/fet2020/members/views.py b/fet2020/members/views.py index 09fddea8..7525e44e 100644 --- a/fet2020/members/views.py +++ b/fet2020/members/views.py @@ -107,7 +107,7 @@ def profile_view(request, member_id=None): logger.info("Wrong member id '{}'".format(member_id)) raise Http404("no member") - jobs = deque(JobMember.members.filter(member__id=member_id)) + jobs = deque(JobMember.members.filter(member__id=member_id).order_by("job_start")) context = { "pinned_job_groups": pinned_job_groups, diff --git a/fet2020/static/js/alpinejs@3.2.2.js b/fet2020/static/js/alpinejs@3.2.2.js new file mode 100644 index 00000000..de5c062e --- /dev/null +++ b/fet2020/static/js/alpinejs@3.2.2.js @@ -0,0 +1,2517 @@ +(() => { + // packages/alpinejs/src/scheduler.js + var flushPending = false; + var flushing = false; + var queue = []; + function scheduler(callback) { + queueJob(callback); + } + function queueJob(job) { + if (!queue.includes(job)) + queue.push(job); + queueFlush(); + } + function queueFlush() { + if (!flushing && !flushPending) { + flushPending = true; + queueMicrotask(flushJobs); + } + } + function flushJobs() { + flushPending = false; + flushing = true; + for (let i = 0; i < queue.length; i++) { + queue[i](); + } + queue.length = 0; + flushing = false; + } + + // packages/alpinejs/src/reactivity.js + var reactive; + var effect; + var release; + var raw; + var shouldSchedule = true; + function disableEffectScheduling(callback) { + shouldSchedule = false; + callback(); + shouldSchedule = true; + } + function setReactivityEngine(engine) { + reactive = engine.reactive; + release = engine.release; + effect = (callback) => engine.effect(callback, {scheduler: (task) => { + if (shouldSchedule) { + scheduler(task); + } else { + task(); + } + }}); + raw = engine.raw; + } + function overrideEffect(override) { + effect = override; + } + function elementBoundEffect(el) { + let cleanup2 = () => { + }; + let wrappedEffect = (callback) => { + let effectReference = effect(callback); + if (!el._x_effects) { + el._x_effects = new Set(); + el._x_runEffects = () => { + el._x_effects.forEach((i) => i()); + }; + } + el._x_effects.add(effectReference); + cleanup2 = () => { + if (effectReference === void 0) + return; + el._x_effects.delete(effectReference); + release(effectReference); + }; + }; + return [wrappedEffect, () => { + cleanup2(); + }]; + } + + // packages/alpinejs/src/mutation.js + var onAttributeAddeds = []; + var onElRemoveds = []; + var onElAddeds = []; + function onElAdded(callback) { + onElAddeds.push(callback); + } + function onElRemoved(callback) { + onElRemoveds.push(callback); + } + function onAttributesAdded(callback) { + onAttributeAddeds.push(callback); + } + function onAttributeRemoved(el, name, callback) { + if (!el._x_attributeCleanups) + el._x_attributeCleanups = {}; + if (!el._x_attributeCleanups[name]) + el._x_attributeCleanups[name] = []; + el._x_attributeCleanups[name].push(callback); + } + function cleanupAttributes(el, names) { + if (!el._x_attributeCleanups) + return; + Object.entries(el._x_attributeCleanups).forEach(([name, value]) => { + (names === void 0 || names.includes(name)) && value.forEach((i) => i()); + delete el._x_attributeCleanups[name]; + }); + } + var observer = new MutationObserver(onMutate); + var currentlyObserving = false; + function startObservingMutations() { + observer.observe(document, {subtree: true, childList: true, attributes: true, attributeOldValue: true}); + currentlyObserving = true; + } + function stopObservingMutations() { + observer.disconnect(); + currentlyObserving = false; + } + var recordQueue = []; + var willProcessRecordQueue = false; + function flushObserver() { + recordQueue = recordQueue.concat(observer.takeRecords()); + if (recordQueue.length && !willProcessRecordQueue) { + willProcessRecordQueue = true; + queueMicrotask(() => { + processRecordQueue(); + willProcessRecordQueue = false; + }); + } + } + function processRecordQueue() { + onMutate(recordQueue); + recordQueue.length = 0; + } + function mutateDom(callback) { + if (!currentlyObserving) + return callback(); + flushObserver(); + stopObservingMutations(); + let result = callback(); + startObservingMutations(); + return result; + } + function onMutate(mutations) { + let addedNodes = []; + let removedNodes = []; + let addedAttributes = new Map(); + let removedAttributes = new Map(); + for (let i = 0; i < mutations.length; i++) { + if (mutations[i].target._x_ignoreMutationObserver) + continue; + if (mutations[i].type === "childList") { + mutations[i].addedNodes.forEach((node) => node.nodeType === 1 && addedNodes.push(node)); + mutations[i].removedNodes.forEach((node) => node.nodeType === 1 && removedNodes.push(node)); + } + if (mutations[i].type === "attributes") { + let el = mutations[i].target; + let name = mutations[i].attributeName; + let oldValue = mutations[i].oldValue; + let add2 = () => { + if (!addedAttributes.has(el)) + addedAttributes.set(el, []); + addedAttributes.get(el).push({name, value: el.getAttribute(name)}); + }; + let remove = () => { + if (!removedAttributes.has(el)) + removedAttributes.set(el, []); + removedAttributes.get(el).push(name); + }; + if (el.hasAttribute(name) && oldValue === null) { + add2(); + } else if (el.hasAttribute(name)) { + remove(); + add2(); + } else { + remove(); + } + } + } + removedAttributes.forEach((attrs, el) => { + cleanupAttributes(el, attrs); + }); + addedAttributes.forEach((attrs, el) => { + onAttributeAddeds.forEach((i) => i(el, attrs)); + }); + for (let node of addedNodes) { + if (removedNodes.includes(node)) + continue; + onElAddeds.forEach((i) => i(node)); + } + for (let node of removedNodes) { + if (addedNodes.includes(node)) + continue; + onElRemoveds.forEach((i) => i(node)); + } + addedNodes = null; + removedNodes = null; + addedAttributes = null; + removedAttributes = null; + } + + // packages/alpinejs/src/scope.js + function addScopeToNode(node, data2, referenceNode) { + node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)]; + return () => { + node._x_dataStack = node._x_dataStack.filter((i) => i !== data2); + }; + } + function refreshScope(element, scope) { + let existingScope = element._x_dataStack[0]; + Object.entries(scope).forEach(([key, value]) => { + existingScope[key] = value; + }); + } + function closestDataStack(node) { + if (node._x_dataStack) + return node._x_dataStack; + if (node instanceof ShadowRoot) { + return closestDataStack(node.host); + } + if (!node.parentNode) { + return []; + } + return closestDataStack(node.parentNode); + } + function mergeProxies(objects) { + return new Proxy({}, { + ownKeys: () => { + return Array.from(new Set(objects.flatMap((i) => Object.keys(i)))); + }, + has: (target, name) => { + return objects.some((obj) => obj.hasOwnProperty(name)); + }, + get: (target, name) => { + return (objects.find((obj) => obj.hasOwnProperty(name)) || {})[name]; + }, + set: (target, name, value) => { + let closestObjectWithKey = objects.find((obj) => obj.hasOwnProperty(name)); + if (closestObjectWithKey) { + closestObjectWithKey[name] = value; + } else { + objects[objects.length - 1][name] = value; + } + return true; + } + }); + } + + // packages/alpinejs/src/interceptor.js + function initInterceptors(data2) { + let isObject2 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null; + let recurse = (obj, basePath = "") => { + Object.entries(obj).forEach(([key, value]) => { + let path = basePath === "" ? key : `${basePath}.${key}`; + if (typeof value === "object" && value !== null && value._x_interceptor) { + obj[key] = value.initialize(data2, path, key); + } else { + if (isObject2(value) && value !== obj && !(value instanceof Element)) { + recurse(value, path); + } + } + }); + }; + return recurse(data2); + } + function interceptor(callback, mutateObj = () => { + }) { + let obj = { + initialValue: void 0, + _x_interceptor: true, + initialize(data2, path, key) { + return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key); + } + }; + mutateObj(obj); + return (initialValue) => { + if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) { + let initialize = obj.initialize.bind(obj); + obj.initialize = (data2, path, key) => { + let innerValue = initialValue.initialize(data2, path, key); + obj.initialValue = innerValue; + return initialize(data2, path, key); + }; + } else { + obj.initialValue = initialValue; + } + return obj; + }; + } + function get(obj, path) { + return path.split(".").reduce((carry, segment) => carry[segment], obj); + } + function set(obj, path, value) { + if (typeof path === "string") + path = path.split("."); + if (path.length === 1) + obj[path[0]] = value; + else if (path.length === 0) + throw error; + else { + if (obj[path[0]]) + return set(obj[path[0]], path.slice(1), value); + else { + obj[path[0]] = {}; + return set(obj[path[0]], path.slice(1), value); + } + } + } + + // packages/alpinejs/src/magics.js + var magics = {}; + function magic(name, callback) { + magics[name] = callback; + } + function injectMagics(obj, el) { + Object.entries(magics).forEach(([name, callback]) => { + Object.defineProperty(obj, `$${name}`, { + get() { + return callback(el, {Alpine: alpine_default, interceptor}); + }, + enumerable: false + }); + }); + return obj; + } + + // packages/alpinejs/src/evaluator.js + function evaluate(el, expression, extras = {}) { + let result; + evaluateLater(el, expression)((value) => result = value, extras); + return result; + } + function evaluateLater(...args) { + return theEvaluatorFunction(...args); + } + var theEvaluatorFunction = normalEvaluator; + function setEvaluator(newEvaluator) { + theEvaluatorFunction = newEvaluator; + } + function normalEvaluator(el, expression) { + let overriddenMagics = {}; + injectMagics(overriddenMagics, el); + let dataStack = [overriddenMagics, ...closestDataStack(el)]; + if (typeof expression === "function") { + return generateEvaluatorFromFunction(dataStack, expression); + } + let evaluator = generateEvaluatorFromString(dataStack, expression); + return tryCatch.bind(null, el, expression, evaluator); + } + function generateEvaluatorFromFunction(dataStack, func) { + return (receiver = () => { + }, {scope = {}, params = []} = {}) => { + let result = func.apply(mergeProxies([scope, ...dataStack]), params); + runIfTypeOfFunction(receiver, result); + }; + } + var evaluatorMemo = {}; + function generateFunctionFromString(expression) { + if (evaluatorMemo[expression]) { + return evaluatorMemo[expression]; + } + let AsyncFunction = Object.getPrototypeOf(async function() { + }).constructor; + let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /^(let|const)/.test(expression) ? `(() => { ${expression} })()` : expression; + let func = new AsyncFunction(["__self", "scope"], `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;`); + evaluatorMemo[expression] = func; + return func; + } + function generateEvaluatorFromString(dataStack, expression) { + let func = generateFunctionFromString(expression); + return (receiver = () => { + }, {scope = {}, params = []} = {}) => { + func.result = void 0; + func.finished = false; + let completeScope = mergeProxies([scope, ...dataStack]); + let promise = func(func, completeScope); + if (func.finished) { + runIfTypeOfFunction(receiver, func.result, completeScope, params); + } else { + promise.then((result) => { + runIfTypeOfFunction(receiver, result, completeScope, params); + }); + } + }; + } + function runIfTypeOfFunction(receiver, value, scope, params) { + if (typeof value === "function") { + let result = value.apply(scope, params); + if (result instanceof Promise) { + result.then((i) => runIfTypeOfFunction(receiver, i, scope, params)); + } else { + receiver(result); + } + } else { + receiver(value); + } + } + function tryCatch(el, expression, callback, ...args) { + try { + return callback(...args); + } catch (e) { + console.warn(`Alpine Expression Error: ${e.message} + +Expression: "${expression}" + +`, el); + throw e; + } + } + + // packages/alpinejs/src/directives.js + var prefixAsString = "x-"; + function prefix(subject = "") { + return prefixAsString + subject; + } + function setPrefix(newPrefix) { + prefixAsString = newPrefix; + } + var directiveHandlers = {}; + function directive(name, callback) { + directiveHandlers[name] = callback; + } + function directives(el, attributes, originalAttributeOverride) { + let transformedAttributeMap = {}; + let directives2 = Array.from(attributes).map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority); + return directives2.map((directive2) => { + return getDirectiveHandler(el, directive2); + }); + } + var isDeferringHandlers = false; + var directiveHandlerStack = []; + function deferHandlingDirectives(callback) { + isDeferringHandlers = true; + let flushHandlers = () => { + while (directiveHandlerStack.length) + directiveHandlerStack.shift()(); + }; + let stopDeferring = () => { + isDeferringHandlers = false; + flushHandlers(); + }; + callback(flushHandlers); + stopDeferring(); + } + function getDirectiveHandler(el, directive2) { + let noop = () => { + }; + let handler3 = directiveHandlers[directive2.type] || noop; + let cleanups = []; + let cleanup2 = (callback) => cleanups.push(callback); + let [effect3, cleanupEffect] = elementBoundEffect(el); + cleanups.push(cleanupEffect); + let utilities = { + Alpine: alpine_default, + effect: effect3, + cleanup: cleanup2, + evaluateLater: evaluateLater.bind(evaluateLater, el), + evaluate: evaluate.bind(evaluate, el) + }; + let doCleanup = () => cleanups.forEach((i) => i()); + onAttributeRemoved(el, directive2.original, doCleanup); + let fullHandler = () => { + if (el._x_ignore || el._x_ignoreSelf) + return; + handler3.inline && handler3.inline(el, directive2, utilities); + handler3 = handler3.bind(handler3, el, directive2, utilities); + isDeferringHandlers ? directiveHandlerStack.push(handler3) : handler3(); + }; + fullHandler.runCleanups = doCleanup; + return fullHandler; + } + var startingWith = (subject, replacement) => ({name, value}) => { + if (name.startsWith(subject)) + name = name.replace(subject, replacement); + return {name, value}; + }; + var into = (i) => i; + function toTransformedAttributes(callback) { + return ({name, value}) => { + let {name: newName, value: newValue} = attributeTransformers.reduce((carry, transform) => { + return transform(carry); + }, {name, value}); + if (newName !== name) + callback(newName, name); + return {name: newName, value: newValue}; + }; + } + var attributeTransformers = []; + function mapAttributes(callback) { + attributeTransformers.push(callback); + } + function outNonAlpineAttributes({name}) { + return alpineAttributeRegex().test(name); + } + var alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\b`); + function toParsedDirectives(transformedAttributeMap, originalAttributeOverride) { + return ({name, value}) => { + let typeMatch = name.match(alpineAttributeRegex()); + let valueMatch = name.match(/:([a-zA-Z0-9\-:]+)/); + let modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []; + let original = originalAttributeOverride || transformedAttributeMap[name] || name; + return { + type: typeMatch ? typeMatch[1] : null, + value: valueMatch ? valueMatch[1] : null, + modifiers: modifiers.map((i) => i.replace(".", "")), + expression: value, + original + }; + }; + } + var DEFAULT = "DEFAULT"; + var directiveOrder = [ + "ignore", + "ref", + "data", + "bind", + "init", + "for", + "model", + "transition", + "show", + "if", + DEFAULT, + "element" + ]; + function byPriority(a, b) { + let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type; + let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type; + return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB); + } + + // packages/alpinejs/src/utils/dispatch.js + function dispatch(el, name, detail = {}) { + el.dispatchEvent(new CustomEvent(name, { + detail, + bubbles: true, + composed: true, + cancelable: true + })); + } + + // packages/alpinejs/src/nextTick.js + var tickStack = []; + var isHolding = false; + function nextTick(callback) { + tickStack.push(callback); + queueMicrotask(() => { + isHolding || setTimeout(() => { + releaseNextTicks(); + }); + }); + } + function releaseNextTicks() { + isHolding = false; + while (tickStack.length) + tickStack.shift()(); + } + function holdNextTicks() { + isHolding = true; + } + + // packages/alpinejs/src/utils/walk.js + function walk(el, callback) { + if (el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => skip = true); + if (skip) + return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } + } + + // packages/alpinejs/src/utils/warn.js + function warn(message, ...args) { + console.warn(`Alpine Warning: ${message}`, ...args); + } + + // packages/alpinejs/src/lifecycle.js + function start() { + if (!document.body) + warn("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + + + + + \ No newline at end of file diff --git a/fet2020/templates/blackboard/index.html b/fet2020/templates/blackboard/index.html index b2ceaed0..0bcbd498 100644 --- a/fet2020/templates/blackboard/index.html +++ b/fet2020/templates/blackboard/index.html @@ -1,46 +1,70 @@ -{% extends 'layout.html' %} +{% extends 'base.html' %} + {% block content %} + +
+

Blackboard

-
- {% if request.user.is_authenticated %} -
- +
+
+
+ + {% if bb_info %} + {{ bb_info.content|safe }} + {% endif %} +
- {% if bb_info %} - - {% endif %} + {% if request.user.is_authenticated and bb_info %} + + Info-Text bearbeiten + + {% endif %} +
- {% if bb_empty %} - - {% endif %} -
-
- {% endif %} + {% if job_postings %} +
+
+ {% for job in job_postings %} + {% if not forloop.first %} +
+ {% endif %} -

Blackboard

+ {% include 'blackboard/partials/_show_job_posting.html' %} + {% endfor %} +
- {% if bb_info %} - {{ bb_info.content|safe }} -
- {% endif %} + {% if request.user.is_authenticated %} + + {% endif %} +
-
- {% for job in job_postings %} - {% include 'blackboard/partials/_show_job_posting.html' %} - {% empty %} - {% if bb_empty %} -
- {{ bb_empty.content|safe }} -
+ {% else %} +
+ {% if bb_empty %} +
+ + {{ bb_empty.content|safe }} +
+ {% endif %} + + {% if request.user.is_authenticated %} +
+ + Neuer Eintrag + + {% if bb_empty %} + + Fülltext bearbeiten + + {% endif %} +
+ {% endif %} +
{% endif %} - {% endfor %} -
-
- +
+
{% endblock %} diff --git a/fet2020/templates/blackboard/partials/_show_job_posting.html b/fet2020/templates/blackboard/partials/_show_job_posting.html index 79dc330e..1cea3b08 100644 --- a/fet2020/templates/blackboard/partials/_show_job_posting.html +++ b/fet2020/templates/blackboard/partials/_show_job_posting.html @@ -1,22 +1,13 @@ -
-

{{job.company_name}}

-

{{job.job_name}}
- - {% if job.number_of_hours == 1 %} - Mindestgehalt: {{job.salary}}€ Stundenlohn

- {% else %} - monatliches Mindestgehalt:
- {{job.salary}}€ für {{job.number_of_hours}}h

- {% endif %} - - {# only thumb and name of member #} - - -
-
-

{{job.company_name}}

-

{{job.job_name}}

-
-
-
-
+ +
+

{{ job.company_name }}

+

{{ job.job_name }}

+
+
+

{{ job.salary }}€

+

/ {{ job.number_of_hours }} h

+
+
+ +
+
diff --git a/fet2020/templates/home.html b/fet2020/templates/home.html index 86135d11..d7c24ca6 100644 --- a/fet2020/templates/home.html +++ b/fet2020/templates/home.html @@ -1,103 +1,93 @@ -{% extends 'layout.html' %} +{% extends 'base.html' %} + {% load post_helpers %} {% load static %} + {% block content %} + +
+
+
+

+ Fachschaft
+ Elektrotechnik +

+ +
-
+ +
+
+

Events

-
-
- -

Events

- - {% with post=featured_event %} +
+ {% if featured_event %} + {% with post=featured_event %} {% include 'posts/partials/_article_row.html' %} - {% endwith %} + {% endwith %} + {% endif %} {% for post in featured_meeting %} - {% include 'posts/partials/_meeting_row.html' %} + {% include 'posts/partials/_article_row.html' %} {% endfor %} -
-
-
-
+ + -
-
- {{ tags_list|tags_to_url }} -
+
+ -
-
- {% for post in posts %} - {% include 'posts/partials/_posts_hero.html' %} - {% endfor %} -
+
+

Zuletzt veröffentlicht

+ + {% for post in posts %} + {% include 'posts/partials/_posts_hero.html' %} + {% endfor %} -
- - - - - - - - - {% for post in events %} - {% include 'posts/partials/_date_box.html' %} - {% endfor %} - - - - -
- -
- - Mehr anzeigen - -
+ Mehr anzeigen + +
+
+
+ + + + + +
+ + FET Discord-Server
+ Klicke hier zum Beitreten +
+ +
+ {% endblock %} diff --git a/fet2020/templates/layout.html b/fet2020/templates/layout.html index 53e31fb3..a28d97a3 100644 --- a/fet2020/templates/layout.html +++ b/fet2020/templates/layout.html @@ -4,19 +4,18 @@ - - - -FET - Fachschaft Elektrotechnik - - - - - -{% block galleryheader %} -{% endblock %} -{% block extraheader %} -{% endblock %} + + + + FET - Fachschaft Elektrotechnik + + + + + {% block galleryheader %} + {% endblock %} + {% block extraheader %} + {% endblock %} diff --git a/fet2020/templates/members/index.html b/fet2020/templates/members/index.html index 4ededad0..82907e0b 100644 --- a/fet2020/templates/members/index.html +++ b/fet2020/templates/members/index.html @@ -1,104 +1,154 @@ -{% extends "layout.html" %} +{% extends 'base.html' %} + {% load softhyphen_tags %} +{% load static %} {% block content %} -
+ +
+

Über uns

+
+ - - -
- - {% if description %} -
-
- {{ description|safe }} -
-
- {% endif %} - - - {% if member %} - {% block members_content %} - {% endblock %} - {% endif %} - - - {% if members %} -
-
- {% if fs_info %} - {{ fs_info.content|safe }} - - {% if request.user.is_authenticated %} -
- Fachschaft-Text bearbeiten -
+
+ {% if description %} +
+ {{ description|safe }} +
{% endif %} - {% endif %} -
-
-
- {% include 'members/members_list.html' %} -
- {% endif %} + {% if member %} + + {% block members_content %} + {% endblock %} + {% endif %} - - {% include 'members/jobs_list.html' %} + {% if members %} + + {% if fs_info %} +
+ {{ fs_info.content|safe }} +
-
+ {% if request.user.is_authenticated %} +
+ Fachschaft-Text bearbeiten +
+ {% endif %} + {% endif %} + +
+
+ {% for member in members %} + {% include 'members/partials/_member.html' %} + {% endfor %} +
+
+ {% endif %} + +
+ + {% include 'members/jobs_list.html' %} +
+ + + + + + + + + + + {% endblock %} - - diff --git a/fet2020/templates/members/jobs_list.html b/fet2020/templates/members/jobs_list.html index 85c4cb82..f536e0bc 100644 --- a/fet2020/templates/members/jobs_list.html +++ b/fet2020/templates/members/jobs_list.html @@ -1,20 +1,17 @@ {% regroup job_members by job.name as all_jobmem_list %} {% for jobmem in all_jobmem_list %} - -
- -

{{jobmem.grouper}} #

- -
- +
+ + +

{{jobmem.grouper}}

+
+
{% for jm in jobmem.list %} {% with member=jm.member %} - {% include 'members/partials/_job_membership_grid.html' %} + {% include 'members/partials/_member.html' %} {% endwith %} {% endfor %} -
-
- -{% endfor %} \ No newline at end of file + +{% endfor %} diff --git a/fet2020/templates/members/member.html b/fet2020/templates/members/member.html index fea55124..3ab40949 100644 --- a/fet2020/templates/members/member.html +++ b/fet2020/templates/members/member.html @@ -1,14 +1,12 @@ {% extends 'members/index.html' %} {% block extraheader %} - - - - + + + + {% endblock %} {% block members_content %} -
- {% include 'members/partials/_member_details.html' %} -
+ {% include 'members/partials/_member_details.html' %} {% endblock %} diff --git a/fet2020/templates/members/members_list.html b/fet2020/templates/members/members_list.html index b08e431c..7b428a30 100644 --- a/fet2020/templates/members/members_list.html +++ b/fet2020/templates/members/members_list.html @@ -1,4 +1,3 @@ -
{% for member in members %}
@@ -7,4 +6,3 @@
{% endfor %}
- diff --git a/fet2020/templates/members/partials/_member.html b/fet2020/templates/members/partials/_member.html index de025a5b..c3cb8a52 100644 --- a/fet2020/templates/members/partials/_member.html +++ b/fet2020/templates/members/partials/_member.html @@ -1,9 +1,8 @@ -{# only thumb and name of member #} - - -
-
-

{{member.nickname}}

-
-
-
+
+ + Portraitfoto von {{ member.firstname }} +
+

{{ member.firstname }} {{ member.surname }}

+
+
+
diff --git a/fet2020/templates/members/partials/_member_details.html b/fet2020/templates/members/partials/_member_details.html index 7d39bfde..c3c8bc6f 100644 --- a/fet2020/templates/members/partials/_member_details.html +++ b/fet2020/templates/members/partials/_member_details.html @@ -1,26 +1,71 @@ {# This template shows one member and all the details (that are ment for public) including a list of current jobs #} {% load softhyphen_tags %} +{% load static %} -
-
- -
-
- {% if request.user.is_authenticated %} - Profil bearbeiten -
- {% endif %} -

{{ member.firstname }} {{ member.surname }}

-

Spitzname: {{ member.nickname }}
- Mailaccount: {{ member.mailaccount }}
-

- {{ member.description|softhyphen|safe }} -

+
+ + Portraitfoto von {{ member.firstname }} {{ member.surname }} +
+

{{ member.firstname }} {{ member.surname }}

+
+ Spitzname: {{ member.nickname }}
+ Mailaccount: {{ member.mailaccount }}
+
+
+ {{ member.description|softhyphen|safe }} +
{% if jobs %} - Ehrenamtliche Tätigkeiten:
- {% for jobm in jobs %} - {{ jobm.job.name }}: {{ jobm.job_start|date }} - {{ jobm.job_end|date }}
- {% endfor %} +

Ehrenamtliche Tätigkeiten: + +

+ +
    + {% for jobm in jobs %} +
  • + {{ jobm.job.name }}: + {{ jobm.job_start|date }} - +
  • + {% endfor %} +
+
    + {% for jobm in jobs %} +
  • + {{ jobm.job.name }}: + {{ jobm.job_start|date }} - +
  • + {% endfor %} +
{% endif %}
-
+ + + + + diff --git a/fet2020/templates/posts/index.html b/fet2020/templates/posts/index.html index 52649886..fdcecef8 100644 --- a/fet2020/templates/posts/index.html +++ b/fet2020/templates/posts/index.html @@ -1,7 +1,132 @@ -{% extends 'layout.html' %} +{% extends 'base.html' %} + {% load post_helpers %} {% block content %} + +
+

News

+
+ + +
+ {% if compact_view %} + {% for post in posts %} + {% include 'posts/partials/_posts_hero_compact.html' %} + {% endfor %} + {% else %} + {% for post in posts %} + {% include 'posts/partials/_posts_hero.html' %} + {% endfor %} + {% endif %} +
+
+
+
@@ -37,21 +162,5 @@
- -
-
- - {% if compact_view %} - {% for post in posts %} - {% include 'posts/partials/_posts_hero_compact.html' %} - {% endfor %} - {% else %} - {% for post in posts %} - {% include 'posts/partials/_posts_hero.html' %} - {% endfor %} - {% endif %} - -
-
{% endblock %} diff --git a/fet2020/templates/posts/partials/_article_row.html b/fet2020/templates/posts/partials/_article_row.html index 9c6fe1a1..2a664016 100644 --- a/fet2020/templates/posts/partials/_article_row.html +++ b/fet2020/templates/posts/partials/_article_row.html @@ -1,12 +1,7 @@ - -
-
-

{{post.title}}

- {% if post.subtitle is not None %} -

{{post.subtitle}}

- {% endif %} - - -
-
+
+

{{ post.title }}

+

+ + {{ post.event_start|date }} · {{ post.event_start|time }} Uhr +

diff --git a/fet2020/templates/posts/partials/_date_box.html b/fet2020/templates/posts/partials/_date_box.html index 21ecc99a..28023bb0 100644 --- a/fet2020/templates/posts/partials/_date_box.html +++ b/fet2020/templates/posts/partials/_date_box.html @@ -1,11 +1,7 @@ - -
- - - {{post.event_start|date:"d"}} - {{post.event_start|date:"M"}} - - - {{post.title}} + +
+ {{ post.event_start|date:"d" }} + {{ post.event_start|date:"M" }}
+

{{ post.title }}

diff --git a/fet2020/templates/posts/partials/_meeting_row.html b/fet2020/templates/posts/partials/_meeting_row.html index c3f164e4..e467eeff 100644 --- a/fet2020/templates/posts/partials/_meeting_row.html +++ b/fet2020/templates/posts/partials/_meeting_row.html @@ -1,11 +1,9 @@ - -
-
-

{{post.title}}

- {% if post.subtitle is not None %} -

{{post.subtitle}}

- {% endif %} - -
-
-
+ diff --git a/fet2020/templates/posts/partials/_posts_hero.html b/fet2020/templates/posts/partials/_posts_hero.html index ced29997..6356cc18 100644 --- a/fet2020/templates/posts/partials/_posts_hero.html +++ b/fet2020/templates/posts/partials/_posts_hero.html @@ -1,9 +1,22 @@ - -
-
-

{{ post.title | safe }}

-

{{ post.subtitle|default_if_none:" " }}

-

{{ post.date|date:"d. F Y" }}

+
diff --git a/fet2020/templates/posts/partials/_posts_hero_compact.html b/fet2020/templates/posts/partials/_posts_hero_compact.html index 7fa267f4..d81d1aef 100644 --- a/fet2020/templates/posts/partials/_posts_hero_compact.html +++ b/fet2020/templates/posts/partials/_posts_hero_compact.html @@ -1,11 +1,13 @@ - -
- - +

{{ post.title | safe | truncatechars:60 }}

+ + diff --git a/fet2020/templates/posts/show.html b/fet2020/templates/posts/show.html index feb7b173..877575ba 100644 --- a/fet2020/templates/posts/show.html +++ b/fet2020/templates/posts/show.html @@ -1,155 +1,245 @@ -{% extends "layout.html" %} +{% extends 'base.html' %} + {% load post_helpers %} {% load admin_urls %} {% block extraheader %} - - - - + + + + {% endblock %} {% block content %} -
-
-
- + +
+ + +
+
+ +

{{ post.title|tags_to_url }}

+
-
-

{{ post.title|tags_to_url }}

-
+
-
- - {{ post.subtitle|default_if_none:" "|tags_to_url }} - - {% if author_image and author %} - - {% elif post.author %} - - {% else %} - +
+ +
+ + {% if post.post_type != 'N' %} + {% endif %} -
-
-
-
-
-
-
- {% for tag in post.get_tagnames %} - {{ tag|tags_to_url }} - {% endfor %} -
+
+
+
+
+ +
+ - {% if post.has_agenda %} -

Agenda #

- {{ post.agenda_html|safe }} -
- {% elif post.body %} - {{ post.body|safe|add_internal_links|tags_to_url }} -
- {% endif %} + {% if request.user.is_authenticated %} +
- {% if request.user.is_authenticated and post.has_protocol %} -

Protokoll #

- {{ post.protocol_html|safe }} -
- {% endif %} + {% if post.has_agenda %} + Agenda + {% if filename_agenda %} + + + + {% endif %} +
+ {% endif %} -
-
- Nächster Artikel
+ {% if post.has_protocol %} + Protokoll + {% if filename_protocol %} + + + + {% endif %} +
+
+ {% endif %} + + {% endif %} + + {% if post.has_agenda %} +

Agenda

+ {{ post.agenda_html|safe }} +
+ {% elif post.body %} + {{ post.body|safe|add_internal_links|tags_to_url }} + {% endif %} + + {% if request.user.is_authenticated and post.has_protocol %} +

Protokoll

+ {{ post.protocol_html|safe }} + {% endif %} +
+ + {% if files %} +
+ Dokumente: + + + + {% endif %} + +
+
+

Termindetails:

+
    +
  • Start: {{ post.event_start|date }} um {{ post.event_start|time }} Uhr
  • +
  • Ende: {{ post.event_end|date }} um {{ post.event_end|time }} Uhr
  • +
+
+
+ +
{% if request.user.is_authenticated %} -
- - {% if post.has_agenda %} - Agenda - {% if filename_agenda %} - - - - {% endif %} -
- {% endif %} - - {% if post.has_protocol %} - Protokoll - {% if filename_protocol %} - - - - {% endif %} -
-
- {% endif %} - {% if post.post_type == 'N' %} - News bearbeiten + + Artikel bearbeiten + {% elif post.post_type == 'E' %} - Event bearbeiten + + Event bearbeiten + {% elif post.post_type == 'F' %} - FET Sitzung bearbeiten + + FET Sitzung bearbeiten + {% endif %} - {% endif %} +
- {% if post.event_start %} -
- Start: {{ post.event_start|date:"d. F Y" }} {{ post.event_start|time:"H:i" }}
- {% endif %} - {% if post.event_end %} - Ende: {{ post.event_end|date:"d. F Y" }} {{ post.event_end|time:"H:i" }}
- {% endif %} - - {% if post.event_place %} - Ort: {{ post.event_place }} - {% endif %} - - {% if post.event_start %} - {% include 'posts/partials/_date_box.html' %} - {% endif %} - - {% if files %} -
- Dokumente: - - - - {% endif %} - -
- -
- -
- -
- {% for post in related_posts %} -
- {% include 'posts/partials/_posts_hero.html' %} -
- {% endfor %} -
-
+ + {% endif %} + {% endblock %} From d2be819786cf3c7860af5e7943117c555cf656a1 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 18 Nov 2021 15:03:05 +0000 Subject: [PATCH 02/24] add sorted jobs --- fet2020/members/managers.py | 14 ++++++++++++++ fet2020/members/views.py | 6 ++++-- .../members/partials/_member_details.html | 8 ++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/fet2020/members/managers.py b/fet2020/members/managers.py index 073ed7c7..f7c6cae4 100644 --- a/fet2020/members/managers.py +++ b/fet2020/members/managers.py @@ -50,6 +50,20 @@ class JobMemberManager(models.Manager): return qs.filter(Q(member__role=role)) + def get_active_jobs(self, member_id): + date_today = timezone.now().date() + qs = self.get_queryset().filter(member__id=member_id).order_by("-job_start") + + return qs.filter(Q(job_end__gt=date_today) | Q(job_end__isnull=True)) + + def get_inactive_jobs(self, member_id): + date_today = timezone.now().date() + qs = self.get_queryset().filter(member__id=member_id).order_by("-job_start") + + return qs.filter( + Q(job_end__lt=date_today + timedelta(days=1)) & Q(job_end__isnull=False) + ) + class JobGroupManager(models.Manager): def get_pinned_jobgroups(self): diff --git a/fet2020/members/views.py b/fet2020/members/views.py index 7525e44e..0cc586ac 100644 --- a/fet2020/members/views.py +++ b/fet2020/members/views.py @@ -107,13 +107,15 @@ def profile_view(request, member_id=None): logger.info("Wrong member id '{}'".format(member_id)) raise Http404("no member") - jobs = deque(JobMember.members.filter(member__id=member_id).order_by("job_start")) + active_jobs = deque(JobMember.members.get_active_jobs(member_id)) + inactive_jobs = deque(JobMember.members.get_inactive_jobs(member_id)) context = { "pinned_job_groups": pinned_job_groups, "unpinned_job_groups": unpinned_job_groups, "member": member, - "jobs": jobs, + "active_jobs": active_jobs, + "inactive_jobs": inactive_jobs, } return render(request, "members/member.html", context) diff --git a/fet2020/templates/members/partials/_member_details.html b/fet2020/templates/members/partials/_member_details.html index c3c8bc6f..4bbf6c0a 100644 --- a/fet2020/templates/members/partials/_member_details.html +++ b/fet2020/templates/members/partials/_member_details.html @@ -14,7 +14,7 @@
{{ member.description|softhyphen|safe }}
- {% if jobs %} + {% if active_jobs or inactive_jobs %}

Ehrenamtliche Tätigkeiten: + {% if inactive_jobs %} + + {% endif %}

    From aa52665dd6bbf1fbb73f8a46838f69504795ba1c Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 22:46:36 +0000 Subject: [PATCH 06/24] add options in news form --- fet2020/posts/views.py | 1 + fet2020/templates/posts/index.html | 153 +++++++++++------------------ 2 files changed, 60 insertions(+), 94 deletions(-) diff --git a/fet2020/posts/views.py b/fet2020/posts/views.py index a1bb1b0b..6e359700 100644 --- a/fet2020/posts/views.py +++ b/fet2020/posts/views.py @@ -50,6 +50,7 @@ def index(request): if year == "": year = None + month = None if not year and month: messages.info( diff --git a/fet2020/templates/posts/index.html b/fet2020/templates/posts/index.html index fdcecef8..d2088cc3 100644 --- a/fet2020/templates/posts/index.html +++ b/fet2020/templates/posts/index.html @@ -27,18 +27,18 @@ x-transition:leave-start="scale-100 opacity-100" x-transition:leave-end="scale-110 opacity-0" > -
    -

    - - - - Auswahl einschränken -

    -
    - -
    -
    -
    +
    +

    + + + + Auswahl einschränken +

    +
    + +
    +
    + {% csrf_token %} {% for message in messages %} @@ -49,54 +49,56 @@
{% endfor %} - - - + + + + + - - - - - - -
- -
-
-
- {% for message in messages %} -

{{message}}

- {% endfor %} -
-
- -
- {% csrf_token %} -
- - {{ formset.management_form }} - - {% for form in formset %} -
- {{ form.label }} - {{ form }} -
- {% endfor %} - -
- - - - - -
- -
- -
-
-
-
{% endblock %} From 381d0759be2fae8b77195ad8d65589df6a88873e Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 22:48:43 +0000 Subject: [PATCH 07/24] fix modal --- fet2020/templates/base.html | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/fet2020/templates/base.html b/fet2020/templates/base.html index e6949ccb..9a550cf6 100644 --- a/fet2020/templates/base.html +++ b/fet2020/templates/base.html @@ -44,7 +44,7 @@ {% endblock %} - +

Zuletzt veröffentlicht

- + + {% if featured_post %} + {% with post=featured_event %} + {% include 'posts/partials/_posts_hero.html' %} + {% endwith %} + {% endif %} + {% for post in posts %} {% include 'posts/partials/_posts_hero.html' %} {% endfor %} From 74733d6ad5bbf863f87ba362198edcba18bd4091 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 22:53:42 +0000 Subject: [PATCH 11/24] update tag links --- fet2020/posts/models.py | 17 +++++++++++++++++ fet2020/posts/views.py | 1 + .../templates/posts/partials/_posts_hero.html | 6 +++--- fet2020/templates/posts/show.html | 6 +++--- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fet2020/posts/models.py b/fet2020/posts/models.py index b9e2f250..c4fca229 100644 --- a/fet2020/posts/models.py +++ b/fet2020/posts/models.py @@ -234,6 +234,23 @@ class Post(models.Model): def tag_string(self): return self.get_tags() + @property + def three_tag_names(self): + tag_lst = [] + count = 0 + + for t in self.tags.names(): + tag_lst.append(t) + count += 1 + if count > 2: + break + + return tag_lst + + @property + def tag_names(self): + return [t for t in self.tags.names()] + @property def imageurl(self): """ diff --git a/fet2020/posts/views.py b/fet2020/posts/views.py index 6e359700..567e0bb4 100644 --- a/fet2020/posts/views.py +++ b/fet2020/posts/views.py @@ -135,6 +135,7 @@ def tags(request, tag=""): "featured_post": featured_post, "job_members": job_members, "tags_list": None, + "tag": tag, } return render(request, "posts/tag.html", context) diff --git a/fet2020/templates/posts/partials/_posts_hero.html b/fet2020/templates/posts/partials/_posts_hero.html index 6356cc18..53f92a85 100644 --- a/fet2020/templates/posts/partials/_posts_hero.html +++ b/fet2020/templates/posts/partials/_posts_hero.html @@ -2,9 +2,9 @@

{{ post.title | safe }}

diff --git a/fet2020/templates/posts/show.html b/fet2020/templates/posts/show.html index 877575ba..356e53dd 100644 --- a/fet2020/templates/posts/show.html +++ b/fet2020/templates/posts/show.html @@ -48,9 +48,9 @@

{{ post.title|tags_to_url }}

From d7b2f2a524c754bbe8d1993d85d7970afa01c945 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 22:54:01 +0000 Subject: [PATCH 12/24] update design for news tag page --- fet2020/templates/posts/tag.html | 66 +++++++------------------------- 1 file changed, 13 insertions(+), 53 deletions(-) diff --git a/fet2020/templates/posts/tag.html b/fet2020/templates/posts/tag.html index b5509fbc..fbe0b3a6 100644 --- a/fet2020/templates/posts/tag.html +++ b/fet2020/templates/posts/tag.html @@ -1,55 +1,15 @@ -{% extends 'layout.html' %} -{% load post_helpers %} +{% extends 'base.html' %} + {% block content %} -{% if featured_post != None %} -{% with post=featured_post %} -
-
-
- -
-

{{post.title | tags_to_url }}

-
-
- {{post.subtitle | tags_to_url }} - {% if post.author_member != None %} - - {% else %} - - {% endif %} - -
-
-
-
-{% endwith %} -{% endif %} - -
- - {% include 'members/jobs_list.html' %} - -
- -
-
-
- {% for post in posts %} - {% include 'posts/partials/_posts_hero.html' %} - {% endfor %} -
-
-
- + +
+

News zu #{{ tag }}

+
+
+ {% for post in posts %} + {% include 'posts/partials/_posts_hero.html' %} + {% endfor %} +
+
+
{% endblock %} From a3188a7f5fa7f154d9e25529f173224647bee5e2 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 22:55:42 +0000 Subject: [PATCH 13/24] update page style --- fet2020/templates/posts/show.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fet2020/templates/posts/show.html b/fet2020/templates/posts/show.html index 356e53dd..6fd8cfd6 100644 --- a/fet2020/templates/posts/show.html +++ b/fet2020/templates/posts/show.html @@ -69,7 +69,7 @@ {% elif post.author %}
- {{ post.author }} + {{ post.author|capfirst }} am {{ post.public_date|date:"d. F Y" }}
@@ -130,8 +130,6 @@ {% if request.user.is_authenticated %} -
- {% if post.has_agenda %} Agenda {% if filename_agenda %} From ef7ace8944b87143d52c8ecedb61a8ebbe53fc18 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 23:00:54 +0000 Subject: [PATCH 14/24] add member change button --- fet2020/templates/members/index.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fet2020/templates/members/index.html b/fet2020/templates/members/index.html index c8e13659..9e5755cb 100644 --- a/fet2020/templates/members/index.html +++ b/fet2020/templates/members/index.html @@ -116,6 +116,14 @@ {% endif %} + + {% if member %} +
  • + + Profil bearbeiten + +
  • + {% endif %} {% endif %}
    From ca9c4649da578168a90b99948c0477876318fd8f Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Wed, 5 Jan 2022 23:23:55 +0000 Subject: [PATCH 15/24] Update Redesign to v0.4.1-beta --- fet2020/static/js/prism-autoloader@1.25.0.js | 515 +++++ fet2020/static/js/prism-core@1.25.0.js | 1221 ++++++++++ fet2020/static/styles.css | 2167 +++++++++--------- fet2020/templates/base.html | 21 +- fet2020/templates/posts/show.html | 4 +- 5 files changed, 2854 insertions(+), 1074 deletions(-) create mode 100644 fet2020/static/js/prism-autoloader@1.25.0.js create mode 100644 fet2020/static/js/prism-core@1.25.0.js diff --git a/fet2020/static/js/prism-autoloader@1.25.0.js b/fet2020/static/js/prism-autoloader@1.25.0.js new file mode 100644 index 00000000..ae93dc13 --- /dev/null +++ b/fet2020/static/js/prism-autoloader@1.25.0.js @@ -0,0 +1,515 @@ +(function () { + + if (typeof Prism === 'undefined' || typeof document === 'undefined') { + return; + } + + /* eslint-disable */ + + /** + * The dependencies map is built automatically with gulp. + * + * @type {Object} + */ + var lang_dependencies = /*dependencies_placeholder[*/{ + "javascript": "clike", + "actionscript": "javascript", + "apex": [ + "clike", + "sql" + ], + "arduino": "cpp", + "aspnet": [ + "markup", + "csharp" + ], + "birb": "clike", + "bison": "c", + "c": "clike", + "csharp": "clike", + "cpp": "c", + "cfscript": "clike", + "chaiscript": [ + "clike", + "cpp" + ], + "coffeescript": "javascript", + "crystal": "ruby", + "css-extras": "css", + "d": "clike", + "dart": "clike", + "django": "markup-templating", + "ejs": [ + "javascript", + "markup-templating" + ], + "etlua": [ + "lua", + "markup-templating" + ], + "erb": [ + "ruby", + "markup-templating" + ], + "fsharp": "clike", + "firestore-security-rules": "clike", + "flow": "javascript", + "ftl": "markup-templating", + "gml": "clike", + "glsl": "c", + "go": "clike", + "groovy": "clike", + "haml": "ruby", + "handlebars": "markup-templating", + "haxe": "clike", + "hlsl": "c", + "idris": "haskell", + "java": "clike", + "javadoc": [ + "markup", + "java", + "javadoclike" + ], + "jolie": "clike", + "jsdoc": [ + "javascript", + "javadoclike", + "typescript" + ], + "js-extras": "javascript", + "json5": "json", + "jsonp": "json", + "js-templates": "javascript", + "kotlin": "clike", + "latte": [ + "clike", + "markup-templating", + "php" + ], + "less": "css", + "lilypond": "scheme", + "liquid": "markup-templating", + "markdown": "markup", + "markup-templating": "markup", + "mongodb": "javascript", + "n4js": "javascript", + "objectivec": "c", + "opencl": "c", + "parser": "markup", + "php": "markup-templating", + "phpdoc": [ + "php", + "javadoclike" + ], + "php-extras": "php", + "plsql": "sql", + "processing": "clike", + "protobuf": "clike", + "pug": [ + "markup", + "javascript" + ], + "purebasic": "clike", + "purescript": "haskell", + "qsharp": "clike", + "qml": "javascript", + "qore": "clike", + "racket": "scheme", + "cshtml": [ + "markup", + "csharp" + ], + "jsx": [ + "markup", + "javascript" + ], + "tsx": [ + "jsx", + "typescript" + ], + "reason": "clike", + "ruby": "clike", + "sass": "css", + "scss": "css", + "scala": "java", + "shell-session": "bash", + "smarty": "markup-templating", + "solidity": "clike", + "soy": "markup-templating", + "sparql": "turtle", + "sqf": "clike", + "squirrel": "clike", + "t4-cs": [ + "t4-templating", + "csharp" + ], + "t4-vb": [ + "t4-templating", + "vbnet" + ], + "tap": "yaml", + "tt2": [ + "clike", + "markup-templating" + ], + "textile": "markup", + "twig": "markup", + "typescript": "javascript", + "v": "clike", + "vala": "clike", + "vbnet": "basic", + "velocity": "markup", + "wiki": "markup", + "xeora": "markup", + "xml-doc": "markup", + "xquery": "markup" + }/*]*/; + + var lang_aliases = /*aliases_placeholder[*/{ + "html": "markup", + "xml": "markup", + "svg": "markup", + "mathml": "markup", + "ssml": "markup", + "atom": "markup", + "rss": "markup", + "js": "javascript", + "g4": "antlr4", + "adoc": "asciidoc", + "avs": "avisynth", + "avdl": "avro-idl", + "shell": "bash", + "shortcode": "bbcode", + "rbnf": "bnf", + "oscript": "bsl", + "cs": "csharp", + "dotnet": "csharp", + "cfc": "cfscript", + "coffee": "coffeescript", + "conc": "concurnas", + "jinja2": "django", + "dns-zone": "dns-zone-file", + "dockerfile": "docker", + "gv": "dot", + "eta": "ejs", + "xlsx": "excel-formula", + "xls": "excel-formula", + "gamemakerlanguage": "gml", + "gni": "gn", + "hbs": "handlebars", + "hs": "haskell", + "idr": "idris", + "gitignore": "ignore", + "hgignore": "ignore", + "npmignore": "ignore", + "webmanifest": "json", + "kt": "kotlin", + "kts": "kotlin", + "kum": "kumir", + "tex": "latex", + "context": "latex", + "ly": "lilypond", + "emacs": "lisp", + "elisp": "lisp", + "emacs-lisp": "lisp", + "md": "markdown", + "moon": "moonscript", + "n4jsd": "n4js", + "nani": "naniscript", + "objc": "objectivec", + "qasm": "openqasm", + "objectpascal": "pascal", + "px": "pcaxis", + "pcode": "peoplecode", + "pq": "powerquery", + "mscript": "powerquery", + "pbfasm": "purebasic", + "purs": "purescript", + "py": "python", + "qs": "qsharp", + "rkt": "racket", + "razor": "cshtml", + "rpy": "renpy", + "robot": "robotframework", + "rb": "ruby", + "sh-session": "shell-session", + "shellsession": "shell-session", + "smlnj": "sml", + "sol": "solidity", + "sln": "solution-file", + "rq": "sparql", + "t4": "t4-cs", + "trig": "turtle", + "ts": "typescript", + "tsconfig": "typoscript", + "uscript": "unrealscript", + "uc": "unrealscript", + "url": "uri", + "vb": "visual-basic", + "vba": "visual-basic", + "mathematica": "wolfram", + "nb": "wolfram", + "wl": "wolfram", + "xeoracube": "xeora", + "yml": "yaml" + }/*]*/; + + /* eslint-enable */ + + /** + * @typedef LangDataItem + * @property {{ success?: () => void, error?: () => void }[]} callbacks + * @property {boolean} [error] + * @property {boolean} [loading] + */ + /** @type {Object} */ + var lang_data = {}; + + var ignored_language = 'none'; + var languages_path = 'components/'; + + var script = Prism.util.currentScript(); + if (script) { + var autoloaderFile = /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i; + var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i; + + var autoloaderPath = script.getAttribute('data-autoloader-path'); + if (autoloaderPath != null) { + // data-autoloader-path is set, so just use it + languages_path = autoloaderPath.trim().replace(/\/?$/, '/'); + } else { + var src = script.src; + if (autoloaderFile.test(src)) { + // the script is the original autoloader script in the usual Prism project structure + languages_path = src.replace(autoloaderFile, 'components/'); + } else if (prismFile.test(src)) { + // the script is part of a bundle like a custom prism.js from the download page + languages_path = src.replace(prismFile, '$1components/'); + } + } + } + + var config = Prism.plugins.autoloader = { + languages_path: languages_path, + use_minified: true, + loadLanguages: loadLanguages + }; + + + /** + * Lazily loads an external script. + * + * @param {string} src + * @param {() => void} [success] + * @param {() => void} [error] + */ + function addScript(src, success, error) { + var s = document.createElement('script'); + s.src = src; + s.async = true; + s.onload = function () { + document.body.removeChild(s); + success && success(); + }; + s.onerror = function () { + document.body.removeChild(s); + error && error(); + }; + document.body.appendChild(s); + } + + /** + * Returns all additional dependencies of the given element defined by the `data-dependencies` attribute. + * + * @param {Element} element + * @returns {string[]} + */ + function getDependencies(element) { + var deps = (element.getAttribute('data-dependencies') || '').trim(); + if (!deps) { + var parent = element.parentElement; + if (parent && parent.tagName.toLowerCase() === 'pre') { + deps = (parent.getAttribute('data-dependencies') || '').trim(); + } + } + return deps ? deps.split(/\s*,\s*/g) : []; + } + + /** + * Returns whether the given language is currently loaded. + * + * @param {string} lang + * @returns {boolean} + */ + function isLoaded(lang) { + if (lang.indexOf('!') >= 0) { + // forced reload + return false; + } + + lang = lang_aliases[lang] || lang; // resolve alias + + if (lang in Prism.languages) { + // the given language is already loaded + return true; + } + + // this will catch extensions like CSS extras that don't add a grammar to Prism.languages + var data = lang_data[lang]; + return data && !data.error && data.loading === false; + } + + /** + * Returns the path to a grammar, using the language_path and use_minified config keys. + * + * @param {string} lang + * @returns {string} + */ + function getLanguagePath(lang) { + return config.languages_path + 'prism-' + lang + (config.use_minified ? '.min' : '') + '.js'; + } + + /** + * Loads all given grammars concurrently. + * + * @param {string[]|string} languages + * @param {(languages: string[]) => void} [success] + * @param {(language: string) => void} [error] This callback will be invoked on the first language to fail. + */ + function loadLanguages(languages, success, error) { + if (typeof languages === 'string') { + languages = [languages]; + } + + var total = languages.length; + var completed = 0; + var failed = false; + + if (total === 0) { + if (success) { + setTimeout(success, 0); + } + return; + } + + function successCallback() { + if (failed) { + return; + } + completed++; + if (completed === total) { + success && success(languages); + } + } + + languages.forEach(function (lang) { + loadLanguage(lang, successCallback, function () { + if (failed) { + return; + } + failed = true; + error && error(lang); + }); + }); + } + + /** + * Loads a grammar with its dependencies. + * + * @param {string} lang + * @param {() => void} [success] + * @param {() => void} [error] + */ + function loadLanguage(lang, success, error) { + var force = lang.indexOf('!') >= 0; + + lang = lang.replace('!', ''); + lang = lang_aliases[lang] || lang; + + function load() { + var data = lang_data[lang]; + if (!data) { + data = lang_data[lang] = { + callbacks: [] + }; + } + data.callbacks.push({ + success: success, + error: error + }); + + if (!force && isLoaded(lang)) { + // the language is already loaded and we aren't forced to reload + languageCallback(lang, 'success'); + } else if (!force && data.error) { + // the language failed to load before and we don't reload + languageCallback(lang, 'error'); + } else if (force || !data.loading) { + // the language isn't currently loading and/or we are forced to reload + data.loading = true; + data.error = false; + + addScript(getLanguagePath(lang), function () { + data.loading = false; + languageCallback(lang, 'success'); + + }, function () { + data.loading = false; + data.error = true; + languageCallback(lang, 'error'); + }); + } + } + + var dependencies = lang_dependencies[lang]; + if (dependencies && dependencies.length) { + loadLanguages(dependencies, load, error); + } else { + load(); + } + } + + /** + * Runs all callbacks of the given type for the given language. + * + * @param {string} lang + * @param {"success" | "error"} type + */ + function languageCallback(lang, type) { + if (lang_data[lang]) { + var callbacks = lang_data[lang].callbacks; + for (var i = 0, l = callbacks.length; i < l; i++) { + var callback = callbacks[i][type]; + if (callback) { + setTimeout(callback, 0); + } + } + callbacks.length = 0; + } + } + + Prism.hooks.add('complete', function (env) { + var element = env.element; + var language = env.language; + if (!element || !language || language === ignored_language) { + return; + } + + var deps = getDependencies(element); + if (/^diff-./i.test(language)) { + // the "diff-xxxx" format is used by the Diff Highlight plugin + deps.push('diff'); + deps.push(language.substr('diff-'.length)); + } else { + deps.push(language); + } + + if (!deps.every(isLoaded)) { + // the language or some dependencies aren't loaded + loadLanguages(deps, function () { + Prism.highlightElement(element); + }); + } + }); + +}()); diff --git a/fet2020/static/js/prism-core@1.25.0.js b/fet2020/static/js/prism-core@1.25.0.js new file mode 100644 index 00000000..cf77da51 --- /dev/null +++ b/fet2020/static/js/prism-core@1.25.0.js @@ -0,0 +1,1221 @@ +/// + +var _self = (typeof window !== 'undefined') + ? window // if in browser + : ( + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + ? self // if in worker + : {} // if in node js + ); + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT + * @author Lea Verou + * @namespace + * @public + */ +var Prism = (function (_self) { + + // Private helper vars + var lang = /\blang(?:uage)?-([\w-]+)\b/i; + var uniqueId = 0; + + // The grammar object for plaintext + var plainTextGrammar = {}; + + + var _ = { + /** + * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the + * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load + * additional languages or plugins yourself. + * + * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. + * + * You obviously have to change this value before the automatic highlighting started. To do this, you can add an + * empty Prism object into the global scope before loading the Prism script like this: + * + * ```js + * window.Prism = window.Prism || {}; + * Prism.manual = true; + * // add a new + - + + + + + + - - + + + - - - - - + diff --git a/fet2020/templates/blackboard/index.html b/fet2020/templates/blackboard/index.html index f1a03b1f..85903d17 100644 --- a/fet2020/templates/blackboard/index.html +++ b/fet2020/templates/blackboard/index.html @@ -1,5 +1,7 @@ {% extends 'base.html' %} +{% block title %}FET: Blackboard{% endblock %} + {% block content %}
    diff --git a/fet2020/templates/flatpages/default.html b/fet2020/templates/flatpages/default.html index 7079942b..4232dc9e 100644 --- a/fet2020/templates/flatpages/default.html +++ b/fet2020/templates/flatpages/default.html @@ -1,5 +1,7 @@ {% extends 'base.html' %} +{% block title %}FET: {{ flatpage.title }}{% endblock %} + {% block content %}
    diff --git a/fet2020/templates/members/jobs.html b/fet2020/templates/members/jobs.html index 43407c57..d4782f43 100644 --- a/fet2020/templates/members/jobs.html +++ b/fet2020/templates/members/jobs.html @@ -1,5 +1,7 @@ {% extends 'members/index.html' %} +{% block title %}FET: {{ active_job_group.name }}{% endblock %} + {% block jobs_content %}

    {{ active_job_group.name }}

    diff --git a/fet2020/templates/members/member.html b/fet2020/templates/members/member.html index a3963b02..638b4929 100644 --- a/fet2020/templates/members/member.html +++ b/fet2020/templates/members/member.html @@ -1,6 +1,8 @@ {% extends 'members/index.html' %} {% load softhyphen_tags %} +{% block title %}FET: {{ member.firstname }} {{ member.surname }}{% endblock %} + {% block extraheader %} diff --git a/fet2020/templates/members/members.html b/fet2020/templates/members/members.html index 69e47a83..f991e8f0 100644 --- a/fet2020/templates/members/members.html +++ b/fet2020/templates/members/members.html @@ -1,5 +1,7 @@ {% extends 'members/index.html' %} +{% block title %}FET: Fachschaft{% endblock %} + {% block members_content %} {% if fs_info %}
    diff --git a/fet2020/templates/posts/index.html b/fet2020/templates/posts/index.html index fa035c91..af1b7abb 100644 --- a/fet2020/templates/posts/index.html +++ b/fet2020/templates/posts/index.html @@ -2,6 +2,8 @@ {% load post_helpers %} +{% block title %}FET: News{% endblock %} + {% block content %}
    diff --git a/fet2020/templates/posts/show.html b/fet2020/templates/posts/show.html index 0c3750a9..d4b55fac 100644 --- a/fet2020/templates/posts/show.html +++ b/fet2020/templates/posts/show.html @@ -3,6 +3,8 @@ {% load post_helpers %} {% load admin_urls %} +{% block title %}FET: News{% endblock %} + {% block extraheader %} diff --git a/fet2020/templates/posts/tag.html b/fet2020/templates/posts/tag.html index fbe0b3a6..3ac955b0 100644 --- a/fet2020/templates/posts/tag.html +++ b/fet2020/templates/posts/tag.html @@ -1,5 +1,7 @@ {% extends 'base.html' %} +{% block title %}FET: News{% endblock %} + {% block content %}