mirror of
https://github.com/Findus23/lw1.at.git
synced 2024-09-10 05:13:46 +02:00
many more changes
This commit is contained in:
parent
2bab4d71af
commit
0bcea6fad5
45 changed files with 923 additions and 646 deletions
18
Makefile
18
Makefile
|
@ -1,4 +1,6 @@
|
|||
all: extract update compile
|
||||
babel: extract update compile
|
||||
|
||||
publish: rmpublic esbuild build upload
|
||||
|
||||
|
||||
extract:
|
||||
|
@ -10,5 +12,15 @@ update:
|
|||
compile:
|
||||
pybabel compile -d translations --statistics
|
||||
|
||||
publish:
|
||||
rsync -aPz public/* lw1.at:/var/www/beta.lw1.at/
|
||||
upload:
|
||||
rsync -aPz --delete-after public/* lw1.at:/var/www/beta.lw1.at/
|
||||
|
||||
esbuild:
|
||||
npm run build
|
||||
|
||||
build:
|
||||
/home/lukas/.virtualenvs/lw1/bin/python lw1/main.py
|
||||
|
||||
rmpublic:
|
||||
rm -r public/
|
||||
mkdir public/
|
||||
|
|
BIN
assets/background.png
Normal file
BIN
assets/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -4,9 +4,7 @@ export function initFeedback() {
|
|||
if (feedbackButton) {
|
||||
feedbackButton.addEventListener("click", ev => {
|
||||
const id = feedbackButton.dataset.id
|
||||
// @ts-ignore
|
||||
if (typeof window._paq != "undefined") {
|
||||
// @ts-ignore
|
||||
window._paq.push(['trackEvent', 'Feedback', 'readmore', id]);
|
||||
} else {
|
||||
console.info("Feedback not sent as Matomo isn't loaded");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {decode} from "blurhash";
|
||||
import {initFeedback} from "./feedback";
|
||||
import {initSearch} from "./search";
|
||||
import {initMatomo} from "./matomo";
|
||||
|
||||
const width = 32;
|
||||
const height = width / 2;
|
||||
|
@ -39,3 +40,4 @@ if (canvasList.length > 5) {
|
|||
|
||||
initFeedback()
|
||||
initSearch()
|
||||
initMatomo()
|
||||
|
|
37
assets/matomo.ts
Normal file
37
assets/matomo.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import {isDebug} from "./utils"
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_paq: paq
|
||||
__PRERENDER_INJECTED: boolean
|
||||
}
|
||||
}
|
||||
|
||||
declare type paq = [[string, unknown, unknown, unknown] | [string, unknown, unknown] | [string, unknown] | [string]]
|
||||
|
||||
|
||||
export function initMatomo(): void {
|
||||
if (isDebug) {
|
||||
return
|
||||
}
|
||||
const _paq = window._paq || [] as unknown as paq
|
||||
_paq.push(['setRequestMethod', 'POST'])
|
||||
_paq.push(['enableHeartBeatTimer'])
|
||||
|
||||
_paq.push(["setDoNotTrack", true])
|
||||
_paq.push(['disableCookies'])
|
||||
const matomoURL = "https://matomo.lw1.at/statistics"
|
||||
_paq.push(['setTrackerUrl', matomoURL + ".php"])
|
||||
_paq.push(['setSiteId', 14])
|
||||
const script = document.createElement('script')
|
||||
const firstScript = document.getElementsByTagName('script')[0]
|
||||
script.type = 'text/javascript'
|
||||
script.async = true
|
||||
script.defer = true
|
||||
script.src = matomoURL + ".js"
|
||||
if (firstScript.parentNode) {
|
||||
firstScript.parentNode.insertBefore(script, firstScript)
|
||||
}
|
||||
window._paq = _paq
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ export function redirect(): void {
|
|||
return
|
||||
|
||||
}
|
||||
l.replace(l.pathname + defaultLanguage() + "/")
|
||||
l.replace("/" + defaultLanguage() + l.pathname)
|
||||
}
|
||||
|
||||
// redirect()
|
||||
redirect()
|
||||
|
|
5
assets/scss/README.md
Normal file
5
assets/scss/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
partially based on milligram.css
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2016 CJ Patoilo <cjpatoilo@gmail.com>
|
18
assets/scss/_base.scss
Normal file
18
assets/scss/_base.scss
Normal file
|
@ -0,0 +1,18 @@
|
|||
@import "variables";
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
background-repeat: repeat;
|
||||
background-image: url("../background.png");
|
||||
image-rendering: pixelated;
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: crisp-edges;
|
||||
background-size: 512px*2;
|
||||
background-attachment: fixed;
|
||||
margin: 0;
|
||||
|
||||
> * {
|
||||
image-rendering: initial;
|
||||
}
|
||||
}
|
||||
|
19
assets/scss/_boxes.scss
Normal file
19
assets/scss/_boxes.scss
Normal file
|
@ -0,0 +1,19 @@
|
|||
@import "variables";
|
||||
|
||||
.note {
|
||||
background-color: $consoleBackground;
|
||||
color: $consoleOrange;
|
||||
font-family: $consoleFont;
|
||||
text-align: center;
|
||||
/*background-color: #fdbc4b;*/
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
a {
|
||||
color: $consoleBlue;
|
||||
|
||||
&:hover, &:focus, &:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
33
assets/scss/_btn.scss
Normal file
33
assets/scss/_btn.scss
Normal file
|
@ -0,0 +1,33 @@
|
|||
@import "variables";
|
||||
|
||||
|
||||
.btn, button, .tag, #filterwrapper > a,
|
||||
input[type='button'],
|
||||
input[type='reset'],
|
||||
input[type='submit'] {
|
||||
background: $consoleBackground;
|
||||
font-family: $consoleFont;
|
||||
padding: .5rem;
|
||||
color: $consoleText;
|
||||
margin: auto auto 1.5rem;
|
||||
line-height: initial;
|
||||
border: none;
|
||||
|
||||
&:focus, &:hover, &:active {
|
||||
outline: $consoleBackground solid 1px;
|
||||
background-color: white;
|
||||
color: $textColor;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $consoleBlue;
|
||||
}
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='button'],
|
||||
input[type='reset'],
|
||||
input[type='submit'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
.contact {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
|
||||
svg {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: $consoleBackground;
|
||||
transition: color .2s;
|
||||
padding: 5px;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
color: $consoleBackground;
|
||||
transition: color .2s;
|
||||
padding: 5px;
|
||||
|
||||
&.keybase .line {
|
||||
fill: currentColor;
|
||||
}
|
||||
&.keybase .line {
|
||||
fill: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
a:hover svg {
|
||||
color: $consoleFocus;
|
||||
outline: 1px solid $consoleFocus;
|
||||
outline: 1px solid $consoleFocus;
|
||||
}
|
||||
}
|
||||
|
|
16
assets/scss/_container.scss
Normal file
16
assets/scss/_container.scss
Normal file
|
@ -0,0 +1,16 @@
|
|||
@import "variables";
|
||||
|
||||
.container {
|
||||
max-width: 1000px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
border: 1px solid $consoleBackground;
|
||||
text-align: center;
|
||||
margin: 20px auto 0;
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
border: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
33
assets/scss/_cornerbuttons.scss
Normal file
33
assets/scss/_cornerbuttons.scss
Normal file
|
@ -0,0 +1,33 @@
|
|||
.topbuttons {
|
||||
@media screen and (max-width: 480px) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.languageSelector, .backButton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 10000;
|
||||
margin: 0;
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
position: initial;
|
||||
display: block;
|
||||
width: 50%;
|
||||
border: 1px solid white;
|
||||
}
|
||||
}
|
||||
|
||||
.languageSelector {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
left: 0;
|
||||
|
||||
.arrow {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
85
assets/scss/_hint-position.scss
Normal file
85
assets/scss/_hint-position.scss
Normal file
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Fork of https://github.com/chinchang/hint.css/blob/master/src/hint-position.scss
|
||||
* remove all but .hint--bottom
|
||||
* MIT License
|
||||
* Copyright (c) 2021 Kushagra Gour
|
||||
*/
|
||||
|
||||
@mixin vertical-positioned-tooltip($propertyY, $transitionDirection, $xDirection:0) {
|
||||
&:before {
|
||||
// bring arrow inside so that it animates to normal position when shown.
|
||||
// HACK: +1px to avoid the 1 px white space between arrow and body during transition.
|
||||
margin-#{$propertyY}: -2 * $hintArrowBorderWidth + 1px;
|
||||
}
|
||||
|
||||
&:before, &:after {
|
||||
#{$propertyY}: 100%;
|
||||
left: 50%; // get top-left corner in center
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: calc(50% - #{$hintArrowBorderWidth}); // get arrow center aligned with content
|
||||
}
|
||||
|
||||
$translateX: -50%;
|
||||
@if $xDirection == -1 {
|
||||
$translateX: -100%;
|
||||
} @else if $xDirection == 1 {
|
||||
$translateX: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
@include vendor('transform', translateX($translateX));
|
||||
}
|
||||
|
||||
&:after {
|
||||
@if $xDirection != 0 {
|
||||
// bring back the tooltip by some offset so that arrow doesn't stick at end
|
||||
margin-left: -$xDirection * $hintArrowOffsetX;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include set-margin('translateY', $transitionDirection, $translateX);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin horizontal-positioned-tooltip($propertyX, $transitionDirection) {
|
||||
&:before {
|
||||
// bring arrow inside so that it animates to normal position when shown
|
||||
// HACK: +1px to avoid the 1 px white space between arrow and body during transition.
|
||||
margin-#{$propertyX}: -2 * $hintArrowBorderWidth + 1px;
|
||||
// bring back to center vertically
|
||||
margin-bottom: -1 * $hintArrowBorderWidth;
|
||||
}
|
||||
|
||||
&:after {
|
||||
// bring back to center
|
||||
margin-bottom: -1 * floor($hintTooltipHeight / 2);
|
||||
}
|
||||
|
||||
&:before, &:after {
|
||||
#{$propertyX}: 100%;
|
||||
bottom: 50%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include set-margin('translateX', $transitionDirection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set default color for tooltip arrows
|
||||
*/
|
||||
.hint--bottom:before {
|
||||
border-bottom-color: $hintDefaultColor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* bottom tooltip
|
||||
*/
|
||||
.#{$hintPrefix}bottom {
|
||||
@include vertical-positioned-tooltip('top', 1);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img.background {
|
||||
background: #f7f7f7 !important;
|
||||
}
|
3
assets/scss/_images.scss
Normal file
3
assets/scss/_images.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
img {
|
||||
max-width: 100%;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
@import "variables";
|
||||
|
||||
|
||||
.intro {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.introduction {
|
||||
text-align: left;
|
||||
|
@ -14,18 +16,18 @@ h1 {
|
|||
cursor: initial !important;
|
||||
|
||||
div {
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
font-size: 24px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
h1 {
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
text-align: left;
|
||||
padding: 0 10px;
|
||||
|
||||
}
|
||||
.languageSelector {
|
||||
right: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
|
23
assets/scss/_others.scss
Normal file
23
assets/scss/_others.scss
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
|
||||
li {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
a svg {
|
||||
fill: initial;
|
||||
}
|
||||
|
||||
|
||||
.toImprint {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
[aria-label][data-balloon-pos] {
|
||||
&::after {
|
||||
font-family: unset !important;
|
||||
background: $consoleBackground !important;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
@import "variables";
|
||||
@import "../node_modules/milligram/src/Color";
|
||||
@import "../node_modules/milligram/src/Utility";
|
||||
|
||||
#blockwrapper {
|
||||
margin: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.card {
|
||||
color: $consoleText;
|
||||
background: $consoleBackground;
|
||||
transition: color .2s;
|
||||
border-radius: $borderRadius;
|
||||
z-index: 3;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
|
@ -14,19 +18,6 @@
|
|||
max-width: 300px;
|
||||
cursor: pointer;
|
||||
|
||||
&:before {
|
||||
border-radius: $borderRadius;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: -3;
|
||||
/*@include shadow(2);*/
|
||||
/*transition: box-shadow 0.2s;*/
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
color: $consoleFocus;
|
||||
|
||||
|
@ -36,16 +27,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.imgwrapper {
|
||||
background: $consoleBackground
|
||||
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
transition: filter .2s;
|
||||
border-top-left-radius: $borderRadius;
|
||||
border-top-right-radius: $borderRadius;
|
||||
height: auto;
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
|
@ -53,6 +37,7 @@
|
|||
|
||||
.imgwrapper {
|
||||
height: 150px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.textwrapper {
|
||||
|
@ -69,47 +54,26 @@
|
|||
}
|
||||
|
||||
.tag {
|
||||
font-family: $consoleFont;
|
||||
display: inline-block;
|
||||
padding: .2em .6em .3em;
|
||||
font-size: 70%;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
border: 1px $consoleText solid;
|
||||
color: $consoleText;
|
||||
background-color: $consoleBackground;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: $borderRadius;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
transition: color .2s, border-color .2s;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
button {
|
||||
color: white;
|
||||
.tag, #filterwrapper > a {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
padding: .3em .6em .3em;
|
||||
|
||||
&.colored {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.active {
|
||||
/*color: darken($color-secondary, 10%);
|
||||
border-color: darken($color-secondary, 10%);
|
||||
background-color: darken(white, 10%) !important;*/
|
||||
color: $consoleFocus;
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: sub;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
#filterwrapper, #searchwrapper, .contact {
|
||||
margin: 0 2rem;
|
||||
}
|
||||
|
||||
#filterwrapper {
|
||||
font-family: monospace, monospace;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
@ -118,21 +82,16 @@ background-color: darken(white, 10%) !important;*/
|
|||
a {
|
||||
display: block;
|
||||
color: $consoleBackground;
|
||||
//text-transform: initial;
|
||||
font-family: $consoleFont;
|
||||
font-size: 1.2rem;
|
||||
padding: .2em .6em;
|
||||
//line-height: 10px;
|
||||
//height: 25px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .1rem;
|
||||
background: white;
|
||||
|
||||
&.active {
|
||||
color: $consoleWhite;
|
||||
color: $consoleWhite !important;
|
||||
outline: none !important;
|
||||
background-color: $consoleBackground;
|
||||
}
|
||||
|
||||
&:focus, &:active, &:hover {
|
||||
color: $consoleBackground;
|
||||
outline: 1px solid $consoleBackground;
|
||||
}
|
||||
}
|
||||
|
@ -145,38 +104,40 @@ background-color: darken(white, 10%) !important;*/
|
|||
font-family: $consoleFont;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
padding: 4px;
|
||||
border: 1px solid #bbb; /* Here */
|
||||
border: none;
|
||||
padding: .5rem;
|
||||
border: 1px solid $consoleBackground;
|
||||
border-radius: $borderRadius;
|
||||
margin-bottom: 0;
|
||||
background-color: $consoleBackground;
|
||||
color: $consoleText;
|
||||
background-color: white;
|
||||
color: $consoleBackground;
|
||||
max-width: 300px;
|
||||
width: 100%;
|
||||
transition: border-color .2s, color .2s;
|
||||
|
||||
&:focus {
|
||||
border-color: $color-primary;
|
||||
border-color: $consoleBlue;
|
||||
outline: none;
|
||||
|
||||
&::placeholder {
|
||||
color: $consoleBlue;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: $consoleText;
|
||||
color: $consoleBackground;
|
||||
transition: color .2s;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::selection {
|
||||
background: $consoleText;
|
||||
color: $consoleBackground;
|
||||
background: $consoleBackground;
|
||||
color: $consoleWhite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#noresults {
|
||||
font-family: $consoleFont;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.gpg {
|
||||
display: block;
|
||||
|
|
|
@ -1,52 +1,9 @@
|
|||
.closeButton {
|
||||
position: absolute;
|
||||
font-size: 22px;
|
||||
line-height: 22px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
color: $color-primary;
|
||||
z-index: 2000;
|
||||
@import "variables";
|
||||
|
||||
&:hover {
|
||||
color: darkgrey;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 0 20px;
|
||||
@media (max-width: 40.0rem) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
z-index: 1000;
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
|
||||
//.modal-container {
|
||||
// position: relative;
|
||||
// max-width: 1000px;
|
||||
// /*
|
||||
// @media (max-width: 40.0rem) {
|
||||
// width: 100%;
|
||||
// padding: 20px;
|
||||
// }
|
||||
//*/
|
||||
// margin: 50px auto 0;
|
||||
// background-color: #fff;
|
||||
// border-radius: $borderRadius;
|
||||
|
||||
.imagewrapper {
|
||||
padding-bottom: 50%;
|
||||
//padding-bottom: 50%;
|
||||
position: relative;
|
||||
background: white;
|
||||
|
||||
&.separator {
|
||||
|
@ -56,31 +13,20 @@
|
|||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-top-left-radius: $borderRadius;
|
||||
border-top-right-radius: $borderRadius;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: relative;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||
//
|
||||
//&:focus {
|
||||
//outline: none;
|
||||
//}
|
||||
//}
|
||||
|
||||
.modal-header h3 {
|
||||
margin-top: 0;
|
||||
color: #42b983;
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 20px 30px;
|
||||
|
@ -88,31 +34,6 @@ h1 {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
.modal-default-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following styles are auto-applied to elements with
|
||||
* transition="modal" when their visibility is toggled
|
||||
* by Vue.js.
|
||||
*
|
||||
* You can easily play with the modal transition by editing
|
||||
* these styles.
|
||||
*/
|
||||
|
||||
.modal-enter {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/*.modal-enter .modal-container,*/
|
||||
/*.modal-leave-active .modal-container {*/
|
||||
/*transform: scale(0.8);*/
|
||||
/*}*/
|
||||
|
||||
.modal-linkbar {
|
||||
display: flex;
|
||||
|
@ -140,12 +61,8 @@ h1 {
|
|||
display: block;
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.try-it-out {
|
||||
color: $color-primary;
|
||||
svg, .try-it-out {
|
||||
color: $linkColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,10 +79,6 @@ h1 {
|
|||
position: relative;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
span {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,12 +92,7 @@ iframe {
|
|||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: $consoleBackground;
|
||||
color: $consoleOrange;
|
||||
font-family: $consoleFont;
|
||||
text-align: center;
|
||||
/*background-color: #fdbc4b;*/
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
#readmore {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
19
assets/scss/_spacing.scss
Normal file
19
assets/scss/_spacing.scss
Normal file
|
@ -0,0 +1,19 @@
|
|||
.button,
|
||||
button,
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
fieldset {
|
||||
margin-bottom: 1rem
|
||||
}
|
||||
|
||||
pre,
|
||||
blockquote,
|
||||
dl,
|
||||
figure,
|
||||
table,
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
margin-bottom: 1.5rem
|
||||
}
|
116
assets/scss/_typography.scss
Normal file
116
assets/scss/_typography.scss
Normal file
|
@ -0,0 +1,116 @@
|
|||
@import "variables";
|
||||
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: $textColor;
|
||||
font-size: 1.8em;
|
||||
font-weight: normal;
|
||||
font-family: $fontFamily;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 300;
|
||||
//letter-spacing: -.1rem;
|
||||
margin-bottom: 2.0rem;
|
||||
margin-top: 0;
|
||||
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4.0rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 3.6rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 3.0rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 2.4rem;
|
||||
letter-spacing: -.08rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.8rem;
|
||||
letter-spacing: -.05rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.6rem;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
|
||||
.texttt {
|
||||
font-family: $consoleFont;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: .3rem solid $gray;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding: 1rem 1.5rem;
|
||||
|
||||
*:last-child {
|
||||
margin-bottom: 0
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: $linkColor;
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
|
||||
a, .btn, button, .tag {
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s, border-color 0.2s
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border-bottom: .1rem solid #e1e1e1;
|
||||
padding: 1.2rem 1.5rem;
|
||||
text-align: left;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0
|
||||
}
|
||||
}
|
|
@ -1,189 +1,30 @@
|
|||
@import "variables";
|
||||
|
||||
|
||||
@import "hint.css/src/hint.base";
|
||||
@import "hint.css/src/hint-variables";
|
||||
@import "hint.css/src/hint-mixins";
|
||||
@import "hint.css/src/hint-core";
|
||||
@import "hint-position";
|
||||
|
||||
@import "../../node_modules/modern-normalize/modern-normalize";
|
||||
@import "variables";
|
||||
@import "../../node_modules/milligram/src/Color";
|
||||
@import "../../node_modules/milligram/src/Vars";
|
||||
@import "../../node_modules/milligram/src/Base";
|
||||
@import "../../node_modules/milligram/src/Blockquote";
|
||||
@import "../../node_modules/milligram/src/Blocks";
|
||||
//@import "../../node_modules/milligram/src/Button";
|
||||
//@import "../../node_modules/milligram/src/Code";
|
||||
@import "../../node_modules/milligram/src/Divider";
|
||||
@import "../../node_modules/milligram/src/Form";
|
||||
@import "../../node_modules/milligram/src/Grid";
|
||||
@import "../../node_modules/milligram/src/Images";
|
||||
@import "../../node_modules/milligram/src/Label";
|
||||
@import "../../node_modules/milligram/src/Link";
|
||||
@import "../../node_modules/milligram/src/List";
|
||||
@import "../../node_modules/milligram/src/Navbar";
|
||||
@import "../../node_modules/milligram/src/Spacing";
|
||||
@import "../../node_modules/milligram/src/Table";
|
||||
@import "../../node_modules/milligram/src/Typography";
|
||||
@import "../../node_modules/milligram/src/Utility";
|
||||
|
||||
|
||||
@import "btn";
|
||||
@import "base";
|
||||
@import "typography";
|
||||
@import "boxes";
|
||||
@import "spacing";
|
||||
@import "images";
|
||||
|
||||
@import "container";
|
||||
@import "cornerbuttons";
|
||||
@import "post";
|
||||
@import "intro";
|
||||
@import "contact";
|
||||
@import "overview";
|
||||
@import "image";
|
||||
@import "code";
|
||||
@import "highlight";
|
||||
@import "license";
|
||||
@import "imprint";
|
||||
@import "langpick";
|
||||
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: white;
|
||||
background-repeat: repeat;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIAAQMAAADOtka5AAAABlBMVEXm5ub///8xREvZAAAFBklEQVR42t1dDZKyMAzt3mP3/tfQe7jDRT7GTwVcTGxfw2OcR0AobTpvptU0zR+WK3kUGuDf1+mb+PyU33GgPgIAZ/Io12GkPgIA93FcfrbfH9/C7dh8FwC43H7Pt/Fsvpfheh2v1+13AYDz6eu8jGnLcxmHx4TOt/izAADNC8MdZmatLc8CAJefaSzTqOLPZWaq6bPhWQDgMZhJ0J23PD+k8zAJ2nHLswCAHdON07+/J27vanffwqP4e4TtAgA0L1juuj+91trtAgB2jVsfPe1+VZ5nu7ddAMDKuvvTo9bZ7qTz+uppFwBwO5/7GOcx97S7XdoseobedgEAmhf8BnzNb7hdAMCPbzp7253W9jw62wUALkYXfo65s70Mr8r4uDz0tgsAzLL+9LXeAzXmwPYvy3S66a58C7a/AADNC3+8tua5Ojfa/gIAy/r2bv1rtS1lea6wK4nbXJVNfwGAp6xf68YN2Wj7l0XSvpPErbalFACwY4J7JDsHdlbRLg1+jZ8HoHnBchferQN2/jxAzVZa05PcmuhWZaC14WX94wBPPXguoe5s+i/SebRlTWO3pQDAMjY3xordxPYvz1k3s1y13Jj+AgA0Lyxc5rntvQXP9hcAaOlDtbvTF14uYMmFX+PnARaZ52RfxZ5u+5eWZl67ry8BgOfex+yBanfbv4zD64k8O7a/AADNC4OFBO49ewoALLpQTSeq6U7LWX7NAd285hAAcINsO9vfyAVzDG1n/wjDBz4PQM9Bgt8BzQsJ1gN6TcwgF1jZmGB/QO+REuwTaV5IqC+EdaYEeiOtOyewH9A2lAx2JJYXEtgTd/cvHNCuTNvWE/oXwj6WBH6m3f0LB/Q30j7XDH5n1veeIP6AjsFIEIdC80KSeCQqJitBXBodm5cgPpGO0cwQp8ryQoJ45d3zFw4Yt07H7ifMXwjncCTIY9k9f+GA+Ux0TleGvDY2ty9BfiOd45kgz5XmhST5zlTOd4K89wub+z9wLx8YBQBAvMEJTMKfHan2QXQBAJoXsLe/TRcAQOseohe48gK6AACMNwD0giQwogsAwH0QoBfo7Qd0AQCaF/COvE0XAOj1sdboBWlmiC4AAPVjQC+93v4aXQAA2UwQvUCrDaALANC8gKx3iC4A0GNDbdEL9PYDugAAsqUjeumx5rfoAgAw3gDQC/LqILoAAM0L2NvfpgsAIB8rohfo5QV0AQAYbwDoBXn7EV0AgJ6DBL8DmhcSrAf0mphBLrCyMcH+gN4jJdgn0ryQSF/YrDMl0Btp3TmB/YC2oWSwI7G8kMCeuJt/4cB2Zdq2nsi/sNnHksDPtJt/4cD+RtrnmsHvjHL9ke8dvW1gIMMHPgBgYzBsjAWi++yBYF0AYPf/X4jWBQDe6UKRuo8KC9YFAKy0i9bfZg9E6gIAbu8TrLso0WhdAIDmBb8Lj9UFAKwuFK377IFgXQDA6cTBusseiNYFAOg5SPA7oHkhwXpAr4kZ5AIrGxPsD+g9UoJ9Is0LSfSFXfMXDqg3Xtq6Mqy7tw9E6wIA7h0Qwbp7C0W0FADYLX9haykAYG2n0dK/nShYCgA4P0KwdG8nipYCAPQcJPgd0LyQYD3Yzb9wZLlgfezBsvr2wt5SAMDGWkRL/zbT4CUAsIt/gbkEAHbRFw7+O7AxeNGr1CIBey8BAPeO6eDl3nIdPQUAdtAXuFMAwMZmR8/ySx4CALxcII//KmY/NmCjfEkAAAAASUVORK5CYII=");
|
||||
image-rendering: pixelated;
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: crisp-edges;
|
||||
background-size: 512px*2;
|
||||
background-attachment: fixed;
|
||||
font-family: -apple-system, "Helvetica Neue Light", "HelveticaNeue", "Helvetica Neue", "Roboto", "Liberation Sans", Arial, sans-serif;
|
||||
font-weight: normal;
|
||||
color: #212121;
|
||||
|
||||
> * {
|
||||
image-rendering: initial;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-color: $consoleBackground white;
|
||||
scrollbar-width: auto;
|
||||
//scrollbar-gutter:stable
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
a svg {
|
||||
fill: initial;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: white;
|
||||
border: 1px solid $consoleBackground;
|
||||
@media (max-width: 1120px) {
|
||||
border: none;
|
||||
}
|
||||
max-width: 1000px;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
#app {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#blockwrapper {
|
||||
margin: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.languageSelector a, .backButton a, .toImprint {
|
||||
|
||||
&:hover, &:focus {
|
||||
color: $consoleBlue;
|
||||
}
|
||||
}
|
||||
|
||||
.languageSelector, .backButton {
|
||||
position: absolute;
|
||||
|
||||
background: $consoleBackground;
|
||||
font-family: $consoleFont;
|
||||
|
||||
a {
|
||||
padding: 5px;
|
||||
color: $consoleText;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.languageSelector, .backButton {
|
||||
top: 0;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.languageSelector {
|
||||
right: 0;
|
||||
|
||||
}
|
||||
|
||||
.backButton {
|
||||
left: 0;
|
||||
|
||||
.arrow {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.toImprint {
|
||||
display: inline-block;
|
||||
background: $consoleBackground;
|
||||
font-family: $consoleFont;
|
||||
padding: 5px;
|
||||
color: $consoleText;
|
||||
margin: auto auto 1.5rem;
|
||||
}
|
||||
|
||||
.texttt {
|
||||
font-family: $consoleFont;
|
||||
}
|
||||
|
||||
.button,
|
||||
button,
|
||||
input[type='button'],
|
||||
input[type='reset'],
|
||||
input[type='submit'] {
|
||||
background-color: $consoleBackground;
|
||||
font-family: $consoleFont;
|
||||
|
||||
cursor: pointer;
|
||||
display: inline-block;;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 700;
|
||||
//height: 3.8rem;
|
||||
letter-spacing: .1rem;
|
||||
line-height: 3.8rem;
|
||||
padding: 0 3.0rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
//white-space: nowrap;
|
||||
border: none;
|
||||
|
||||
&:focus, &:hover, &:active {
|
||||
outline: $consoleBackground solid 1px;
|
||||
background-color: transparent;
|
||||
color: $consoleBackground;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
[aria-label][data-balloon-pos] {
|
||||
&::after {
|
||||
font-family: unset !important;
|
||||
background: $consoleBackground !important;
|
||||
}
|
||||
}
|
||||
@import "others";
|
||||
|
|
|
@ -2,6 +2,10 @@ $color-primary: #303f9f;
|
|||
$borderRadius: 0px;
|
||||
$imageheight: 150px;
|
||||
|
||||
$textColor: #212121;
|
||||
|
||||
$linkColor: #303f9f;
|
||||
|
||||
$consoleBackground: #31363B;
|
||||
$consoleWhite: #EFF0F1;
|
||||
$consoleOrange: #FDBC4B;
|
||||
|
@ -9,10 +13,14 @@ $consoleBlue: #3DAEE9;
|
|||
$consoleGreen: #16A085;
|
||||
$consoleRed: #963830;
|
||||
|
||||
$gray: #cacacc;
|
||||
|
||||
|
||||
$consoleFocus: $consoleBlue;
|
||||
$consoleText: $consoleWhite;
|
||||
$consoleFont: "Fira Code Retina", monospace, monospace;
|
||||
|
||||
$fontFamily: -apple-system, "Helvetica Neue Light", "HelveticaNeue", "Helvetica Neue", "Liberation Sans", "Roboto", Arial, sans-serif;
|
||||
|
||||
@mixin dark() {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
|
2
assets/utils.ts
Normal file
2
assets/utils.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const isDebug = document.body.dataset.debug == "True"
|
||||
|
5
build.ts
5
build.ts
|
@ -14,7 +14,8 @@ const commonOption: BuildOptions = {
|
|||
loader: {
|
||||
".ttf": "file",
|
||||
".woff": "file",
|
||||
".woff2": "file"
|
||||
".woff2": "file",
|
||||
".png": "base64"
|
||||
},
|
||||
entryNames: "[name]"
|
||||
}
|
||||
|
@ -23,7 +24,7 @@ const commonOption: BuildOptions = {
|
|||
switch (process.argv[2]) {
|
||||
case "build":
|
||||
commonOption.metafile = true
|
||||
commonOption.entryNames = "[dir]/[name]-[hash]"
|
||||
commonOption.entryNames = "[name]-[hash]"
|
||||
build(commonOption).then(result => {
|
||||
fs.writeFileSync(commonOption.outdir + "/meta.json", JSON.stringify(result.metafile))
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
id: masterarbeit
|
||||
#id: masterarbeit
|
||||
tags:
|
||||
- python
|
||||
- latex
|
||||
|
|
|
@ -7,6 +7,7 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape, StrictUndef
|
|||
from lw1.paths import templates_dir, cache_dir
|
||||
from lw1.post import Post
|
||||
from lw1.settings import FALLBACK_LANGUAGES
|
||||
from lw1.sitemap import Sitemap
|
||||
from lw1.tag import Tag
|
||||
from lw1.types import Language
|
||||
from lw1.writer import Writer
|
||||
|
@ -26,10 +27,11 @@ class Generator:
|
|||
type = ""
|
||||
|
||||
def __init__(self, translations: Translations, context: Dict, posts: List[Post], tags: Dict[str, Tag],
|
||||
lang: Language, ):
|
||||
lang: Language, sitemap: Sitemap):
|
||||
self.posts = posts
|
||||
self.tags = tags
|
||||
self.lang = lang
|
||||
self.sitemap = sitemap
|
||||
self.context = context.copy()
|
||||
self.context["js_entry_point"] = self.js_entry_point
|
||||
self.context["type"] = self.type
|
||||
|
@ -45,21 +47,17 @@ class PostsGenerator(Generator):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def url(self, post: Post) -> Path:
|
||||
print(post.title)
|
||||
return Path("") / self.lang / post.slug
|
||||
|
||||
def generate(self, writer: Writer) -> None:
|
||||
for post in self.posts:
|
||||
if post.lang != self.lang:
|
||||
continue
|
||||
for image in {post.content_img, post.thumbnail_img}:
|
||||
writer.writeImage((Path("") / "img" / post.id), image)
|
||||
writer.writeImage((Path("") / "img" / post.slug), image)
|
||||
self.context["post"] = post
|
||||
self.context["otherlang_url"] = post.other_lang_post.absolute_url
|
||||
html = self.template.render(**self.context)
|
||||
url = self.url(post)
|
||||
writer.write(url, html)
|
||||
writer.write(post.absolute_url, html)
|
||||
self.sitemap.add_post(post)
|
||||
|
||||
|
||||
class HomepageGenerator(Generator):
|
||||
|
@ -75,16 +73,19 @@ class HomepageGenerator(Generator):
|
|||
self.context["current"] = "all"
|
||||
self.context["posts"] = [p for p in self.posts if p.lang == self.lang]
|
||||
self.context["otherlang_url"] = Path("/") / other_lang
|
||||
self.context["otherlang"] = other_lang
|
||||
url = Path("/") / self.lang
|
||||
self.context["url"] = url
|
||||
self.sitemap.add_page(self.context)
|
||||
html = self.template.render(**self.context)
|
||||
url = Path("") / self.lang
|
||||
writer.write(url, html)
|
||||
for tag in self.tags.values():
|
||||
self.context["current"] = tag.id
|
||||
|
||||
if tag.hidden:
|
||||
continue
|
||||
|
||||
self.context["posts"] = [p for p in self.posts if p.lang == self.lang and tag.id in p.tags]
|
||||
url = Path("") / self.lang / "t" / tag.slug_in_lang(self.lang)
|
||||
url = Path("/") / self.lang / "t" / tag.slug_in_lang(self.lang)
|
||||
self.context["otherlang_url"] = Path("/") / other_lang / "t" / tag.slug_in_lang(other_lang)
|
||||
html = self.template.render(**self.context)
|
||||
|
||||
|
@ -103,10 +104,13 @@ class ImprintGenerator(Generator):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def generate(self, writer: Writer) -> None:
|
||||
fb_lang = FALLBACK_LANGUAGES[self.lang]
|
||||
self.context["otherlang_url"] = Path("/") / fb_lang / self.slugs[fb_lang]
|
||||
other_lang = FALLBACK_LANGUAGES[self.lang]
|
||||
url = Path("/") / self.lang / self.slugs[self.lang]
|
||||
self.context["otherlang_url"] = Path("/") / other_lang / self.slugs[other_lang]
|
||||
self.context["otherlang"] = other_lang
|
||||
self.context["url"] = url
|
||||
self.sitemap.add_page(self.context)
|
||||
html = self.template.render(**self.context)
|
||||
url = Path("") / self.lang / self.slugs[self.lang]
|
||||
writer.write(url, html)
|
||||
|
||||
|
||||
|
@ -119,6 +123,9 @@ class LangRedirectGenerator(Generator):
|
|||
|
||||
def generate(self, writer: Writer) -> None:
|
||||
html = self.template.render(**self.context)
|
||||
root = Path("")
|
||||
for url in [root, root / "i"]:
|
||||
root = Path("/")
|
||||
paths = {root, root / "i"}
|
||||
for post in self.posts:
|
||||
paths.add(root / post.slug)
|
||||
for url in paths:
|
||||
writer.write(url, html)
|
||||
|
|
11
lw1/main.py
11
lw1/main.py
|
@ -4,11 +4,14 @@ from babel.support import Translations
|
|||
|
||||
from lw1.generators import PostsGenerator, HomepageGenerator, ImprintGenerator, LangRedirectGenerator
|
||||
from lw1.loader import PostLoader, TagsLoader, AssetsLoader
|
||||
from lw1.paths import output_dir
|
||||
from lw1.settings import LANGUAGES
|
||||
from lw1.sitemap import Sitemap
|
||||
from lw1.writer import Writer
|
||||
|
||||
|
||||
def main(debug=False):
|
||||
sitemap = Sitemap()
|
||||
start = perf_counter_ns()
|
||||
posts = PostLoader.load_posts()
|
||||
tags = TagsLoader.load_tags()
|
||||
|
@ -25,8 +28,14 @@ def main(debug=False):
|
|||
LangRedirectGenerator
|
||||
]
|
||||
for cls in generators:
|
||||
g = cls(posts=posts, tags=tags, lang=lang, context=context, translations=translations)
|
||||
g = cls(
|
||||
posts=posts, tags=tags,
|
||||
lang=lang, context=context,
|
||||
translations=translations,
|
||||
sitemap=sitemap
|
||||
)
|
||||
g.generate(writer)
|
||||
sitemap.dump(output_dir / "sitemap.xml")
|
||||
end = perf_counter_ns()
|
||||
print(f"{(end - start) / 1000 / 1000:.2f} ms")
|
||||
|
||||
|
|
26
lw1/post.py
26
lw1/post.py
|
@ -2,13 +2,14 @@ from __future__ import annotations
|
|||
|
||||
from dataclasses import dataclass
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
from slugify import slugify
|
||||
|
||||
from lw1.file import Image
|
||||
from lw1.settings import DOMAIN
|
||||
from lw1.tomarkdown import markdown2html
|
||||
from lw1.types import Language
|
||||
from lw1.utils import custom_slugify
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -20,20 +21,21 @@ class License:
|
|||
@dataclass
|
||||
class iFrame:
|
||||
url: str
|
||||
allowfullscreen: bool
|
||||
sandbox: str
|
||||
color: str
|
||||
sandbox: str = None
|
||||
allowfullscreen: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class Post:
|
||||
id: str
|
||||
title: str
|
||||
tags: List[str]
|
||||
date: str
|
||||
markdown: str
|
||||
content_img: Image
|
||||
thumbnail_img: Image
|
||||