Compare commits

..

No commits in common. "632f47e017f4f4f7a121e091341a3cd8140ccf49" and "54d1f0292e7cedd983dbaeb29680eb69082ab55c" have entirely different histories.

4 changed files with 53 additions and 141 deletions

View File

@ -10,7 +10,7 @@ dependencies = [
dynamic = []
authors = []
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.10"
classifiers = []
version = "0.0.0"

View File

@ -4,23 +4,3 @@ Here you will learn how to get started making your own website.
1. fork the project and clone the fork
2. {{installation.link}}
## File structure
The files that define the content can be found in `src`. There are 3 subfolders. The style and functionality is defined in `templates`. If you can't code, or you don't know what your doing, leave it alone. The static files like stylesheets or pictures exist in `static`. This folder is simply copied on build. The interesting part starts with `articles`. Here are (like the name implies) all articles.
If something remains unclear, then the code of this documentation (should be found in your fork) could be helpful.
## Write articles
The text for the articles follows the following naming scheme `<language_code>.md`. In this case it would be `en.md` then you can write the article normally using [markdown](https://www.markdownguide.org/) for formatting.
If there should be subarticles, just create a new folder in the parent article folder. The folder name will be used as slug. That means it will appear in the url, and you can use it to link to other articles.
If you want to define the metadata for the article (the name, creation date, or author), then you can do so in `index.toml`. If none exists you can just create one. Here an example of such a file.
```toml
name="stsg"
datetime="2024-04-15 13:45:12.123456"
author="Hazel"
```

View File

@ -8,9 +8,6 @@ class config:
fallback_language = "en"
preview_length = 400
preview_header_shift = 2
markdown_extras = [
"fenced-code-blocks"
]
languages = {
"af": {

View File

@ -10,12 +10,9 @@ from collections import defaultdict
import toml
from datetime import datetime
import jinja2
from functools import cached_property
from . import config
def get_first_header_content(content, fallback: str = ""):
soup = BeautifulSoup(content, 'html.parser')
for level in range(1, 7):
@ -81,6 +78,19 @@ def get_preview_text(html_string: str):
return shift_headings(shorten_text_and_clean(html_string))
def stem_to_language_code(stem: str) -> str:
language_code = stem.lower().replace("-", "_")
if language_code in config.languages:
return language_code
language_code = language_code.split("_")[0]
if language_code in config.languages:
return language_code
logger.error("Didn't recognize %s as a valid language code, add it to the config, or fix your structure.", stem)
exit(1)
class TemplateDict(dict):
def __init__(self, folder: Path):
@ -127,66 +137,28 @@ def compile_cross_article_context(cross_article_context):
cross_article_context["link"] = f'<a href="{url}">{title}</a>'
class ArticleTranslationContext(TypedDict):
slug: str
name: str
datetime: str
author: str
url: str
class ArticleTranslation:
article: Article
file: Path
@cached_property
def html_content(self) -> str:
html_content = self.file.read_text()
if self.file.suffix == ".md":
return markdown(html_content, extras=config.formatting.markdown_extras)
return html_content
@cached_property
def language_code(self) -> str:
language_code = self.file.stem.lower().replace("-", "_")
if language_code in config.languages:
return language_code
language_code = language_code.split("_")[0]
if language_code in config.languages:
return language_code
logger.error("Didn't recognize %s as a valid language code, add it to the config, or fix your structure.", stem)
exit(1)
@cached_property
def priority(self) -> int:
return LANGUAGES[self.language_code]["priority"]
@cached_property
def slug_path(self) -> List[str]:
return [self.language_code, *self.article.slug_path]
@cached_property
def url(self) -> str:
return "/" + "/".join(self.slug_path)
@cached_property
def dist_path(self) -> Path:
return Path(config.setup.dist_directory, *self.slug_path)
context: ArticleTranslationContext
cross_article_context: Dict[str, Any]
def __init__(self, file: Path, article: Article):
self.article = article
self.file = file
self.article = article
self.context = {}
self.context: Dict[str, Any] = {}
# initializing the location of the article translation
self.language_code = stem_to_language_code(self.file.stem)
self.location_in_tree = [self.language_code, *self.article.location_in_tree]
self.url = "/" + "/".join(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.real_language_code = LANGUAGES[self.language_code]["code"]
self.html_content = self.file.read_text()
if self.file.suffix == ".md":
self.html_content = markdown(self.html_content, extras=["fenced-code-blocks"])
def __init_context__(self):
self.context["meta"] = self.article.context_shared
self.context["url"] = self.url
@ -239,70 +211,33 @@ class ArticleTranslation:
f.write(TEMPLATE["article_translation"].render(self.context))
class ArticleConfig(TypedDict):
slug: str
name: str
datetime: str
author: str
class ArticleContext(TypedDict):
slug: str
name: str
datetime: str
author: str
url: str
class Article:
directory: Path
@cached_property
def config(self) -> ArticleConfig:
config_file = self.directory / "index.toml"
return toml.load(config_file) if config_file.exists() else {}
@cached_property
def slug(self) -> str:
slug = self.config.get("name", self.directory.name)
if slug in ARTICLE_LAKE:
logger.error("two articles have the same name at %s and %r", ARTICLE_LAKE[slug].directory, self.directory)
exit(1)
return slug
@cached_property
def name(self) -> str:
return self.config.get("name", self.slug)
article_path: List[Article]
@cached_property
def slug_path(self) -> List[str]:
return [a.slug for a in self.article_path[1:]]
@cached_property
def url(self) -> str:
return "/" + "/".join(self.slug_path)
@cached_property
def dist_path(self) -> Path:
return Path(config.setup.dist_directory, *self.slug_path)
context: ArticleContext
context_shared: Dict[str, Any]
cross_article_context: Dict[str, Any]
def __init__(self, directory: Path, article_path: Optional[List[str]] = None, is_root: bool = False, parent: Optional[Article] = None):
def __init__(self, directory: Path, location_in_tree: Optional[List[str]] = None, is_root: bool = False, parent: Optional[Article] = None):
self.directory = directory
self.article_path: List[Article] = article_path or []
self.article_path.append(self)
self.context: Dict[str, Any] = {}
self.context_shared: Dict[str, Any] = {}
if parent is not None:
self.context["parent"] = parent.context_shared
self.context: ArticleContext = {}
self.context_shared = {}
# initializing the config values of the article
config_file = self.directory / "index.toml"
self.config = toml.load(config_file) if config_file.exists() else {}
# initializing the location and slug of the article
self.slug = self.config.get("name", self.directory.name)
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)
exit(1)
self.cross_article_context = CROSS_ARTICLE_CONTEXT[self.slug] = {}
ARTICLE_LAKE[self.slug] = self
self.location_in_tree: List[str] = location_in_tree or []
if not is_root:
self.location_in_tree.append(self.slug)
self.url = "/" + "/".join(self.location_in_tree)
self.dist_path = Path(config.setup.dist_directory, *self.location_in_tree)
# build the tree
self.child_articles: List[Article] = []
self.article_translations_list: List[ArticleTranslation] = []
@ -319,13 +254,13 @@ class Article:
elif c.is_dir():
self.child_articles.append(Article(
directory=c,
article_path=self.article_path.copy(),
location_in_tree=self.location_in_tree.copy(),
parent=self,
))
self.article_translations_list.sort(key=lambda a: a.priority, reverse=True)
logger.info("found %s at %s with the translations %s", self.slug, ".".join(list(self.slug_path)), ",".join(self.article_translations_map.keys()))
logger.info("found %s at %s with the translations %s", self.slug, ".".join(list(self.location_in_tree)), ",".join(self.article_translations_map.keys()))
def __init_context__(self):
self.context_shared["url"] = self.url
@ -347,7 +282,7 @@ class Article:
child_article_list = self.context["children"] = []
for article_translation in self.article_translations_list:
self.context[article_translation.language_code] = article_translation.context
self.context[article_translation.real_language_code] = article_translation.context
translation_list.append(article_translation.context)
for child_article in self.child_articles: