Compare commits

...

2 Commits

Author SHA1 Message Date
Hazel Noack
f84fb65aa7 feat: fallback to overview page 2025-05-16 15:12:22 +02:00
Hazel Noack
d019884dbe implemented data structure for cross article context 2025-05-16 15:01:09 +02:00
3 changed files with 55 additions and 17 deletions

View File

@ -4,6 +4,8 @@ meow
## Usque de celebrabant puer ## Usque de celebrabant puer
[{{index_page.title}}]({{index_page.url}})
Lorem markdownum, nec ora et vero me nec natae suadent. Nec damno ignorat Lorem markdownum, nec ora et vero me nec natae suadent. Nec damno ignorat
propiore aliquid temptata decipienda habetur. Vulnera lacrimis aequoreo madidos, propiore aliquid temptata decipienda habetur. Vulnera lacrimis aequoreo madidos,
copia uvae, herbosaque quoque, per harenas, canos fui monstro Peleus. copia uvae, herbosaque quoque, per harenas, canos fui monstro Peleus.

View File

@ -1,6 +1,6 @@
# Navê Gotarê # Navê Gotarê
[{article_title:example}]({article_url:example}) [{{example.title}}]({{example.url}})
Ev gotar, mînakek placeholder ya bi zimanê Kurdî ye. Nivîs, weşan û rûpelên nûçe di vê belgeyê de têne pêşniyar kirin. Ev metn ji bo testkirina layout an jî demo-yê hatiye çêkirin û çend bingehên cihanî yên naveroka gotarê nîşan dide. Ev gotar, mînakek placeholder ya bi zimanê Kurdî ye. Nivîs, weşan û rûpelên nûçe di vê belgeyê de têne pêşniyar kirin. Ev metn ji bo testkirina layout an jî demo-yê hatiye çêkirin û çend bingehên cihanî yên naveroka gotarê nîşan dide.
@ -35,4 +35,4 @@ Kodê li ser vê koda simplesa gotinê ye û dikare weşana nûçe an demo-yê p
# Encama Gotarê # Encama Gotarê
Di encama gotarê de, hûn dikarin her çend beşên bingehîn yên nûçe, daxuyanî û şirove yên navekî bifikirin. Di encama gotarê de, hûn dikarin her çend beşên bingehîn yên nûçe, daxuyanî û şirove yên navekî bifikirin.
Bê guman, ev placeholder bi awayek qelew li ser çalakiya te ya malper, blog an jî her sedema dijîtal tê de karîger e. Bê guman, ev placeholder bi awayek qelew li ser çalakiya te ya malper, blog an jî her sedema dijîtal tê de karîger e.

View File

@ -4,7 +4,7 @@ import shutil
from pathlib import Path from pathlib import Path
import os import os
import markdown import markdown
from typing import Optional, Union, Dict, Generator, List, DefaultDict, Any from typing import Optional, Union, Dict, Generator, List, DefaultDict, Any, TypedDict, Set
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from collections import defaultdict from collections import defaultdict
import toml import toml
@ -13,7 +13,6 @@ import jinja2
from . import config from . import config
def get_first_header_content(content, fallback: str = ""): def get_first_header_content(content, fallback: str = ""):
soup = BeautifulSoup(content, 'html.parser') soup = BeautifulSoup(content, 'html.parser')
for level in range(1, 7): for level in range(1, 7):
@ -143,26 +142,43 @@ class ArticleTranslation:
self.location_in_tree = [self.language_code, *self.article.location_in_tree] self.location_in_tree = [self.language_code, *self.article.location_in_tree]
self.url = "/" + "/".join(self.location_in_tree) self.url = "/" + "/".join(self.location_in_tree)
self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree) self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree)
self.cross_article_context = TRANSLATED_CROSS_ARTICLE_CONTEXT[self.language_code][self.article.slug] = {}
self.priority = LANGUAGES[self.language_code]["priority"] self.priority = LANGUAGES[self.language_code]["priority"]
self.real_language_code = LANGUAGES[self.language_code]["code"] self.real_language_code = LANGUAGES[self.language_code]["code"]
self.html_content = self.file.read_text()
if self.file.suffix == ".md":
self.html_content = markdown.markdown(self.html_content)
def __init_context__(self): def __init_context__(self):
self.context["meta"] = self.article.context_shared self.context["meta"] = self.article.context_shared
self.context["url"] = self.url self.context["url"] = self.url
self.context["language"] = LANGUAGES[self.language_code] self.context["language"] = LANGUAGES[self.language_code]
self.context["article_url"] = self.article.url self.context["article_url"] = self.article.url
self.context["title"] = get_first_header_content(self.html_content, fallback=LANGUAGES[self.language_code]["native_name"])
html_content = self.file.read_text() self.cross_article_context.update(self.article.context_shared)
if self.file.suffix == ".md": self.cross_article_context["title"] = self.context["title"]
html_content = markdown.markdown(html_content) self.cross_article_context["article_url"] = self.article.url
self.cross_article_context["url"] = self.url
self.context["title"] = get_first_header_content(html_content, fallback=LANGUAGES[self.language_code]["native_name"])
self.context["content"] = html_content
self.context["preview"] = get_preview_text(html_string=html_content)
# get children # get children
self.context["children"] = [c.article_translations_map[self.language_code].context for c in self.article.child_articles if self.language_code in c.article_translations_map] self.context["children"] = [
c.article_translations_map[self.language_code].context for c in self.article.child_articles
if self.language_code in c.article_translations_map
]
def __init_content_context__(self):
template = jinja2.Template(self.html_content)
self.html_content = template.render({
**CROSS_ARTICLE_CONTEXT,
**TRANSLATED_CROSS_ARTICLE_CONTEXT[self.language_code],
})
self.context["content"] = self.html_content
self.context["preview"] = get_preview_text(html_string=self.html_content)
def build(self): def build(self):
self.dist_path.mkdir(parents=True, exist_ok=True) self.dist_path.mkdir(parents=True, exist_ok=True)
@ -189,6 +205,7 @@ class Article:
if self.slug in ARTICLE_LAKE: if self.slug in ARTICLE_LAKE:
logger.error("two articles have the same name at %s and %r", ARTICLE_LAKE[self.slug].directory, self.directory) logger.error("two articles have the same name at %s and %r", ARTICLE_LAKE[self.slug].directory, self.directory)
exit(1) exit(1)
self.cross_article_context = CROSS_ARTICLE_CONTEXT[self.slug] = {}
ARTICLE_LAKE[self.slug] = self ARTICLE_LAKE[self.slug] = self
self.location_in_tree: List[str] = location_in_tree or [] self.location_in_tree: List[str] = location_in_tree or []
@ -231,6 +248,11 @@ class Article:
self.context.update(self.context_shared) self.context.update(self.context_shared)
self.cross_article_context.update(self.context_shared)
self.cross_article_context["title"] = self.context_shared["slug"]
self.cross_article_context["article_url"] = self.context_shared["url"]
# recursive context structures # recursive context structures
translation_list = self.context["translations"] = [] translation_list = self.context["translations"] = []
child_article_list = self.context["children"] = [] child_article_list = self.context["children"] = []
@ -248,9 +270,15 @@ class Article:
for a in self.child_articles: for a in self.child_articles:
a.__init_context__() a.__init_context__()
def __init_content_context__(self):
for at in self.article_translations_list:
at.__init_content_context__()
for a in self.child_articles:
a.__init_content_context__()
def build(self): def build(self):
self.dist_path.mkdir(parents=True, exist_ok=True) self.dist_path.mkdir(parents=True, exist_ok=True)
with Path(self.dist_path, "index.html").open("w") as f: with Path(self.dist_path, "index.html").open("w") as f:
f.write(TEMPLATE["article"].render(self.context)) f.write(TEMPLATE["article"].render(self.context))
@ -263,24 +291,32 @@ class Article:
# GLOBALS # GLOBALS
logger = logging.getLogger("stsg.build") logger = logging.getLogger("stsg.build")
CROSS_ARTICLE_CONTEXT: Dict[str, Dict[str, Any]] = {}
TRANSLATED_CROSS_ARTICLE_CONTEXT: Dict[str, Dict[str, Dict[str, Any]]] = defaultdict(dict)
ARTICLE_LAKE: Dict[str, Article] = {} ARTICLE_LAKE: Dict[str, Article] = {}
ARTICLE_REFERENCE_VALUES: DefaultDict[str, Dict[str, str]] = defaultdict(dict) ARTICLE_REFERENCE_VALUES: DefaultDict[str, Dict[str, str]] = defaultdict(dict)
def build(): def build():
logger.info("starting build process...") logger.info("starting build process...")
logger.info("copying static folder...") logger.info("copying static folder...")
shutil.copytree(Path(config.setup.source_directory, "static"), Path(config.setup.dist_directory, "static"), dirs_exist_ok=True) shutil.copytree(Path(config.setup.source_directory, "static"), Path(config.setup.dist_directory, "static"), dirs_exist_ok=True)
logger.info("building page tree...") logger.info("building page tree...")
tree = Article(directory=Path(config.setup.source_directory, "articles"), is_root=True) tree = Article(directory=Path(config.setup.source_directory, "articles"), is_root=True)
logger.info("compiling tree context...") logger.info("compiling tree context...")
tree.__init_context__() tree.__init_context__()
tree.__init_content_context__()
import json import json
with Path("context.json").open("w") as f: with Path("context.json").open("w") as f:
json.dump(tree.context, f, indent=4) json.dump(tree.context, f, indent=4)
with Path("cross_article_context.json").open("w") as f:
json.dump(CROSS_ARTICLE_CONTEXT, f, indent=4)
with Path("t_cross_article_context.json").open("w") as f:
json.dump(TRANSLATED_CROSS_ARTICLE_CONTEXT, f, indent=4)
logger.info("dumping page tree...") logger.info("dumping page tree...")
tree.build() tree.build()