Skip to content

Commit

Permalink
Add templates folder to config and improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Siecje committed Feb 5, 2024
1 parent 6e66ec1 commit 494caaa
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 32 deletions.
27 changes: 15 additions & 12 deletions htmd/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,21 @@ def build(
from . import site
app = site.app

if css_minify:
assert app.static_folder is not None
combine_and_minify_css(Path(app.static_folder))

if js_minify:
assert app.static_folder is not None
combine_and_minify_js(Path(app.static_folder))

if css_minify or js_minify:
# reload to set app.config['INCLUDE_CSS'] and app.config['INCLUDE_JS']
# setting them here doesn't work
importlib.reload(site)
assert app.static_folder is not None
static_path = Path(app.static_folder)
if static_path.is_dir():
if css_minify:
assert app.static_folder is not None
combine_and_minify_css(static_path)

if js_minify:
assert app.static_folder is not None
combine_and_minify_js(static_path)

if css_minify or js_minify:
# reload to set app.config['INCLUDE_CSS'] and app.config['INCLUDE_JS']
# setting them here doesn't work
importlib.reload(site)

set_posts_datetime(site.app, site.posts)

Expand Down
7 changes: 4 additions & 3 deletions htmd/example_site/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ url = ""

# Where to look for files
[folders]
static = "static"
posts = "posts"
pages = "pages"
build = "build"
pages = "pages"
posts = "posts"
static = "static"
templates = "templates"

[posts]
extension = ".md"
Expand Down
44 changes: 27 additions & 17 deletions htmd/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ def get_project_dir() -> Path:
project_dir = get_project_dir()


app = Flask(
__name__,
static_folder=project_dir / 'static',
template_folder=this_dir / 'example_site' / 'templates',
)


try:
with (project_dir / 'config.toml').open('rb') as config_file:
htmd_config = tomllib.load(config_file)
Expand All @@ -64,24 +57,34 @@ def get_project_dir() -> Path:
'SITE_TWITTER': ('site', 'twitter', ''),
'SITE_FACEBOOK': ('site', 'facebook', ''),
'FACEBOOK_APP_ID': ('site', 'facebook_app_id', ''),
'STATIC_FOLDER': ('folders', 'static', 'static'),
'POSTS_FOLDER': ('folders', 'posts', 'posts'),
'PAGES_FOLDER': ('folders', 'pages', 'pages'),

'BUILD_FOLDER': ('folders', 'build', 'build'),
'PAGES_FOLDER': ('folders', 'pages', 'pages'),
'POSTS_FOLDER': ('folders', 'posts', 'posts'),
'STATIC_FOLDER': ('folders', 'static', 'static'),
'TEMPLATE_FOLDER': ('folders', 'templates', 'templates'),

'POSTS_EXTENSION': ('posts', 'extension', '.md'),

'PRETTY_HTML': ('html', 'pretty', False),
'MINIFY_HTML': ('html', 'minify', False),

'SHOW_AUTHOR': ('author', 'show', True),
'DEFAULT_AUTHOR': ('author', 'default_name', ''),
'DEFAULT_AUTHOR_TWITTER': ('author', 'default_twitter', ''),
'DEFAULT_AUTHOR_FACEBOOK': ('author', 'default_facebook', ''),
}
app = Flask(
__name__,
# default templates
template_folder=this_dir / 'example_site' / 'templates',
)
# Update app.config using the configuration keys
for flask_key, (table, key, default) in config_keys.items():
app.config[flask_key] = htmd_config.get(table, {}).get(key, default)
app.static_folder = project_dir / app.config['STATIC_FOLDER']
assert app.static_folder is not None


# To avoid full paths in config.toml
app.config['FLATPAGES_ROOT'] = (
project_dir / app.config['POSTS_FOLDER']
Expand All @@ -92,8 +95,9 @@ def get_project_dir() -> Path:
app.config['FREEZER_REMOVE_EXTRA_FILES'] = False
app.config['FLATPAGES_EXTENSION'] = app.config['POSTS_EXTENSION']

app.config['INCLUDE_CSS'] = 'combined.min.css' in os.listdir(app.static_folder)
app.config['INCLUDE_JS'] = 'combined.min.js' in os.listdir(app.static_folder)
if Path(app.static_folder).is_dir():
app.config['INCLUDE_CSS'] = 'combined.min.css' in os.listdir(app.static_folder)
app.config['INCLUDE_JS'] = 'combined.min.js' in os.listdir(app.static_folder)


posts = FlatPages(app)
Expand Down Expand Up @@ -122,7 +126,7 @@ def truncate_post_html(post_html: str) -> str:

# Include current htmd site templates
app.jinja_loader = ChoiceLoader([ # type: ignore[assignment]
FileSystemLoader(project_dir / 'templates/'),
FileSystemLoader(project_dir / app.config['TEMPLATE_FOLDER']),
app.jinja_loader, # type: ignore[list-item]
])

Expand Down Expand Up @@ -167,7 +171,10 @@ def format_html(response: Response) -> ResponseReturnValue:
def page(path: str) -> ResponseReturnValue:
# ensure page is from pages directory
# otherwise this will load any templates in the template folder
for page_path in (project_dir / 'pages').iterdir():
pages_folder = project_dir / app.config['PAGES_FOLDER']
if not pages_folder.is_dir():
abort(404)
for page_path in pages_folder.iterdir():
if path == page_path.stem:
break
else:
Expand Down Expand Up @@ -436,8 +443,11 @@ def draft() -> Iterator[dict]: # noqa: F811

@freezer.register_generator # type: ignore[no-redef]
def page() -> Iterator[str]: # noqa: F811
for page in (project_dir / 'pages').iterdir():
pages_folder = project_dir / app.config['PAGES_FOLDER']
if not pages_folder.is_dir():
return
for page in pages_folder.iterdir():
# Need to create for pages.page
# Since this route is in a different Blueprint
# URL works
# Using the URL works
yield f'/{page.stem}/'
56 changes: 56 additions & 0 deletions tests/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,59 @@ def test_build_page_without_link(run_start: CliRunner) -> None:
assert result.exit_code == 0
with (Path('build') / 'new' / 'index.html').open('r') as page_file:
assert 'Totally new' in page_file.read()


def test_build_empty_directory() -> None:
expected = 'Can not find config.toml\n'
runner = CliRunner()
with runner.isolated_filesystem():
result = runner.invoke(build)
assert result.exit_code == 1
assert result.output == expected


def test_build_without_static(run_start: CliRunner) -> None:
path = Path('static')
shutil.rmtree(path)
result = run_start.invoke(build)
assert result.exit_code == 0
assert re.search(SUCCESS_REGEX, result.output)


def test_build_without_posts(run_start: CliRunner) -> None:
path = Path('posts')
shutil.rmtree(path)
result = run_start.invoke(build)
assert result.exit_code == 0
assert re.search(SUCCESS_REGEX, result.output)


def test_build_without_pages(run_start: CliRunner) -> None:
path = Path('pages')
shutil.rmtree(path)

result = run_start.invoke(build)
assert result.exit_code == 1
assert "Unexpected status '404 NOT FOUND' on URL /about/" in result.output

# Remove link from _layout.html
layout_path = Path('templates') / '_layout.html'
with layout_path.open('r') as layout_file:
lines = layout_file.readlines()
with layout_path.open('w') as layout_file:
for line in lines:
if 'about' in line:
continue
layout_file.write(line)

result = run_start.invoke(build)
assert result.exit_code == 0
assert re.search(SUCCESS_REGEX, result.output)


def test_build_without_templates(run_start: CliRunner) -> None:
path = Path('templates')
shutil.rmtree(path)
result = run_start.invoke(build)
assert result.exit_code == 0
assert re.search(SUCCESS_REGEX, result.output)

0 comments on commit 494caaa

Please sign in to comment.