mirror of
https://github.com/venthur/blag.git
synced 2025-11-25 20:52:43 +00:00
Merge branch 'master' into split_archive
This commit is contained in:
21
CHANGELOG.md
21
CHANGELOG.md
@@ -2,10 +2,22 @@
|
|||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
|
||||||
* **Breaking Change**: Split former archive page which served as index.html
|
### Breaking
|
||||||
into "index" and "archive", each with their own template, respectively. Index
|
|
||||||
is the landing page and shows by default only the latest 10 articles. Archive
|
* blag does not use default fallback templates anymore and will return an error
|
||||||
shows the full list of articles.
|
if it is unable to find required templates, e.g. in `templates/`.
|
||||||
|
|
||||||
|
Users upgrading from older versions can either run `blag quickstart` (don't
|
||||||
|
forget to backup your `config.ini` or copy the templates from blag's
|
||||||
|
resources (the resource path is shown in the error message).
|
||||||
|
|
||||||
|
New users are not affected as `blag quickstart` will generate the needed
|
||||||
|
templates.
|
||||||
|
|
||||||
|
* Split former archive page which served as index.html into "index" and
|
||||||
|
"archive", each with their own template, respectively. Index is the landing
|
||||||
|
page and shows by default only the latest 10 articles. Archive shows the full
|
||||||
|
list of articles.
|
||||||
|
|
||||||
If you used custom templates,
|
If you used custom templates,
|
||||||
* you should create an "index.html"-template (take blag's default one as a
|
* you should create an "index.html"-template (take blag's default one as a
|
||||||
@@ -13,6 +25,7 @@
|
|||||||
* you may want to include the new "/archive.html" link somewhere in your
|
* you may want to include the new "/archive.html" link somewhere in your
|
||||||
navigation
|
navigation
|
||||||
|
|
||||||
|
|
||||||
## [1.5.0] - 2023-04-16
|
## [1.5.0] - 2023-04-16
|
||||||
|
|
||||||
* moved to pyproject.toml
|
* moved to pyproject.toml
|
||||||
|
|||||||
43
blag/blag.py
43
blag/blag.py
@@ -16,13 +16,13 @@ import sys
|
|||||||
|
|
||||||
from jinja2 import (
|
from jinja2 import (
|
||||||
Environment,
|
Environment,
|
||||||
ChoiceLoader,
|
|
||||||
FileSystemLoader,
|
FileSystemLoader,
|
||||||
PackageLoader,
|
|
||||||
Template,
|
Template,
|
||||||
|
TemplateNotFound,
|
||||||
)
|
)
|
||||||
import feedgenerator
|
import feedgenerator
|
||||||
|
|
||||||
|
import blag
|
||||||
from blag.markdown import markdown_factory, convert_markdown
|
from blag.markdown import markdown_factory, convert_markdown
|
||||||
from blag.devserver import serve
|
from blag.devserver import serve
|
||||||
from blag.version import __VERSION__
|
from blag.version import __VERSION__
|
||||||
@@ -185,15 +185,14 @@ def get_config(configfile: str) -> configparser.SectionProxy:
|
|||||||
|
|
||||||
|
|
||||||
def environment_factory(
|
def environment_factory(
|
||||||
template_dir: str | None = None,
|
template_dir: str,
|
||||||
globals_: dict[str, object] | None = None,
|
globals_: dict[str, object] | None = None,
|
||||||
) -> Environment:
|
) -> Environment:
|
||||||
"""Environment factory.
|
"""Environment factory.
|
||||||
|
|
||||||
Creates a Jinja2 Environment with the default templates and
|
Creates a Jinja2 Environment with the templates from `template_dir` loaded.
|
||||||
additional templates from `template_dir` loaded. If `globals` are
|
If `globals` are provided, they are attached to the environment and thus
|
||||||
provided, they are attached to the environment and thus available to
|
available to all contexts.
|
||||||
all contexts.
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
@@ -206,13 +205,7 @@ def environment_factory(
|
|||||||
jinja2.Environment
|
jinja2.Environment
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# first we try the custom templates, and fall back the ones provided
|
env = Environment(loader=FileSystemLoader(template_dir))
|
||||||
# by blag
|
|
||||||
loaders: list[FileSystemLoader | PackageLoader] = []
|
|
||||||
if template_dir:
|
|
||||||
loaders.append(FileSystemLoader([template_dir]))
|
|
||||||
loaders.append(PackageLoader('blag', 'templates'))
|
|
||||||
env = Environment(loader=ChoiceLoader(loaders))
|
|
||||||
if globals_:
|
if globals_:
|
||||||
env.globals = globals_
|
env.globals = globals_
|
||||||
return env
|
return env
|
||||||
@@ -261,12 +254,22 @@ def build(args: argparse.Namespace) -> None:
|
|||||||
|
|
||||||
env = environment_factory(args.template_dir, dict(site=config))
|
env = environment_factory(args.template_dir, dict(site=config))
|
||||||
|
|
||||||
page_template = env.get_template('page.html')
|
try:
|
||||||
article_template = env.get_template('article.html')
|
page_template = env.get_template('page.html')
|
||||||
index_template = env.get_template('index.html')
|
article_template = env.get_template('article.html')
|
||||||
archive_template = env.get_template('archive.html')
|
index_template = env.get_template('index.html')
|
||||||
tags_template = env.get_template('tags.html')
|
archive_template = env.get_template('archive.html')
|
||||||
tag_template = env.get_template('tag.html')
|
tags_template = env.get_template('tags.html')
|
||||||
|
tag_template = env.get_template('tag.html')
|
||||||
|
except TemplateNotFound as exc:
|
||||||
|
tmpl = os.path.join(blag.__path__[0], 'templates')
|
||||||
|
logger.error(
|
||||||
|
f'Template "{exc.name}" not found in {args.template_dir}! '
|
||||||
|
'Consider running `blag quickstart` or copying the '
|
||||||
|
f'missing template from {tmpl}.'
|
||||||
|
)
|
||||||
|
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
articles, pages = process_markdown(
|
articles, pages = process_markdown(
|
||||||
convertibles,
|
convertibles,
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import configparser
|
import configparser
|
||||||
import argparse
|
import argparse
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
|
import blag
|
||||||
|
|
||||||
|
|
||||||
def get_input(question: str, default: str) -> str:
|
def get_input(question: str, default: str) -> str:
|
||||||
@@ -33,6 +37,22 @@ def get_input(question: str, default: str) -> str:
|
|||||||
return reply
|
return reply
|
||||||
|
|
||||||
|
|
||||||
|
def copy_templates() -> None:
|
||||||
|
"""Copy templates into current directory.
|
||||||
|
|
||||||
|
It will not overwrite existing files.
|
||||||
|
|
||||||
|
"""
|
||||||
|
print("Copying templates...")
|
||||||
|
try:
|
||||||
|
shutil.copytree(
|
||||||
|
os.path.join(blag.__path__[0], 'templates'),
|
||||||
|
'templates',
|
||||||
|
)
|
||||||
|
except FileExistsError:
|
||||||
|
print("Templates already exist. Skipping.")
|
||||||
|
|
||||||
|
|
||||||
def quickstart(args: argparse.Namespace | None) -> None:
|
def quickstart(args: argparse.Namespace | None) -> None:
|
||||||
"""Quickstart.
|
"""Quickstart.
|
||||||
|
|
||||||
@@ -71,3 +91,5 @@ def quickstart(args: argparse.Namespace | None) -> None:
|
|||||||
}
|
}
|
||||||
with open('config.ini', 'w') as fh:
|
with open('config.ini', 'w') as fh:
|
||||||
config.write(fh)
|
config.write(fh)
|
||||||
|
|
||||||
|
copy_templates()
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Install blag from PyPI_
|
|||||||
|
|
||||||
.. _pypi: https://pypi.org/project/blag/
|
.. _pypi: https://pypi.org/project/blag/
|
||||||
|
|
||||||
Run blag's quickstart command to create the configuration needed
|
Run blag's quickstart command to create the configuration and templates needed
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
@@ -40,8 +40,8 @@ If you want more separation between the static files and the markdown content,
|
|||||||
you can put all static files into the ``static`` directory. Blag will copy
|
you can put all static files into the ``static`` directory. Blag will copy
|
||||||
them over to the ``build`` directory.
|
them over to the ``build`` directory.
|
||||||
|
|
||||||
If you want to customize the looks of the generated site, create a
|
If you want to customize the look of the generated site, visit the ``template``
|
||||||
``template`` directory and put your jinja2 templates here.
|
directory. It contains jinja2 templates and can be modified as needed.
|
||||||
|
|
||||||
Those directories can be changed via command line arguments. See
|
Those directories can be changed via command line arguments. See
|
||||||
|
|
||||||
@@ -186,9 +186,7 @@ becomes
|
|||||||
Templating
|
Templating
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Custom templates are **optional** and stored by default in the ``templates``
|
Templates are stored by default in the ``templates`` directory.
|
||||||
directory. blag will search the ``templates`` directory first, and fall back
|
|
||||||
to blag's default built-in templates.
|
|
||||||
|
|
||||||
============ ====================================== ===================
|
============ ====================================== ===================
|
||||||
Template Used For Variables
|
Template Used For Variables
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ import os
|
|||||||
import pytest
|
import pytest
|
||||||
from jinja2 import Environment, Template
|
from jinja2 import Environment, Template
|
||||||
|
|
||||||
from blag import blag
|
from blag import blag, quickstart
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def environment() -> Iterator[Environment]:
|
def environment(cleandir: str) -> Iterator[Environment]:
|
||||||
site = {
|
site = {
|
||||||
'base_url': 'site base_url',
|
'base_url': 'site base_url',
|
||||||
'title': 'site title',
|
'title': 'site title',
|
||||||
'description': 'site description',
|
'description': 'site description',
|
||||||
'author': 'site author',
|
'author': 'site author',
|
||||||
}
|
}
|
||||||
env = blag.environment_factory(globals_=dict(site=site))
|
env = blag.environment_factory('templates', globals_=dict(site=site))
|
||||||
yield env
|
yield env
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ def tag_template(environment: Environment) -> Iterator[Template]:
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def cleandir() -> Iterator[str]:
|
def cleandir() -> Iterator[str]:
|
||||||
"""Create a temporary workind directory and cwd."""
|
"""Create a temporary working directory and cwd."""
|
||||||
config = """
|
config = """
|
||||||
[main]
|
[main]
|
||||||
base_url = https://example.com/
|
base_url = https://example.com/
|
||||||
@@ -65,13 +65,14 @@ author = a. u. thor
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
with TemporaryDirectory() as dir:
|
with TemporaryDirectory() as dir:
|
||||||
for d in 'content', 'build', 'static', 'templates':
|
for d in 'content', 'build', 'static':
|
||||||
os.mkdir(f'{dir}/{d}')
|
os.mkdir(f'{dir}/{d}')
|
||||||
with open(f'{dir}/config.ini', 'w') as fh:
|
with open(f'{dir}/config.ini', 'w') as fh:
|
||||||
fh.write(config)
|
fh.write(config)
|
||||||
# change directory
|
# change directory
|
||||||
old_cwd = os.getcwd()
|
old_cwd = os.getcwd()
|
||||||
os.chdir(dir)
|
os.chdir(dir)
|
||||||
|
quickstart.copy_templates()
|
||||||
yield dir
|
yield dir
|
||||||
# and change back afterwards
|
# and change back afterwards
|
||||||
os.chdir(old_cwd)
|
os.chdir(old_cwd)
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ author = a. u. thor
|
|||||||
assert config_parsed['base_url'] == 'https://example.com/'
|
assert config_parsed['base_url'] == 'https://example.com/'
|
||||||
|
|
||||||
|
|
||||||
def test_environment_factory() -> None:
|
def test_environment_factory(cleandir: str) -> None:
|
||||||
globals_: dict[str, object] = {'foo': 'bar', 'test': 'me'}
|
globals_: dict[str, object] = {'foo': 'bar', 'test': 'me'}
|
||||||
env = blag.environment_factory(globals_=globals_)
|
env = blag.environment_factory("templates", globals_=globals_)
|
||||||
assert env.globals['foo'] == 'bar'
|
assert env.globals['foo'] == 'bar'
|
||||||
assert env.globals['test'] == 'me'
|
assert env.globals['test'] == 'me'
|
||||||
|
|
||||||
@@ -301,6 +301,23 @@ foo bar
|
|||||||
assert os.path.exists(f'{args.output_dir}/tags/bar.html')
|
assert os.path.exists(f'{args.output_dir}/tags/bar.html')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'template',
|
||||||
|
[
|
||||||
|
'page.html',
|
||||||
|
'article.html',
|
||||||
|
'index.html',
|
||||||
|
'archive.html',
|
||||||
|
'tags.html',
|
||||||
|
'tag.html',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_missing_template_raises(template: str, args: Namespace) -> None:
|
||||||
|
os.remove(f'templates/{template}')
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
blag.build(args)
|
||||||
|
|
||||||
|
|
||||||
def test_main(cleandir: str) -> None:
|
def test_main(cleandir: str) -> None:
|
||||||
blag.main(['build'])
|
blag.main(['build'])
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# remove when we don't support py38 anymore
|
# remove when we don't support py38 anymore
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
import os
|
||||||
|
|
||||||
from pytest import MonkeyPatch
|
from pytest import MonkeyPatch
|
||||||
|
|
||||||
@@ -27,3 +28,13 @@ def test_quickstart(cleandir: str, monkeypatch: MonkeyPatch) -> None:
|
|||||||
assert 'title = foo' in data
|
assert 'title = foo' in data
|
||||||
assert 'description = foo' in data
|
assert 'description = foo' in data
|
||||||
assert 'author = foo' in data
|
assert 'author = foo' in data
|
||||||
|
|
||||||
|
for template in (
|
||||||
|
"archive.html",
|
||||||
|
"article.html",
|
||||||
|
"base.html",
|
||||||
|
"page.html",
|
||||||
|
"tag.html",
|
||||||
|
"tags.html",
|
||||||
|
):
|
||||||
|
assert os.path.exists(f'templates/{template}')
|
||||||
|
|||||||
Reference in New Issue
Block a user