Skip to content

Add examples#7

Merged
rartino merged 2 commits intomainfrom
develop
Mar 27, 2026
Merged

Add examples#7
rartino merged 2 commits intomainfrom
develop

Conversation

@rartino
Copy link
Copy Markdown
Member

@rartino rartino commented Mar 27, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 27, 2026 00:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a large set of runnable modern + legacy examples, while expanding the core engine’s compatibility-mode behavior to better support legacy .httkweb.html templates and legacy site initialization/config patterns.

Changes:

  • Implement legacy .httkweb.html rendering via a new HttkTemplateFormatter and integrate it into HttkCompatTemplateEngine.
  • Add site-wide config loading (config_name*) + startup functions/init.py support, and extend legacy list/frontmatter normalization.
  • Add multiple modern and legacy example sites (templates/content/functions/assets) plus expanded compatibility-mode tests.

Reviewed changes

Copilot reviewed 121 out of 128 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/test_api.py Adds compatibility-mode tests for legacy repeat/pages calls, config loading, and init execution.
src/httk/web/templating/httk_compat.py Extends compat engine to render legacy .httkweb.html via a formatter while keeping Jinja for modern templates.
src/httk/web/templating/_legacy_formatter.py Introduces a legacy formatter supporting repeat/call/getitem/getattr/if + escaping behavior.
src/httk/web/renderers/_frontmatter.py Extends *-list normalization to support comma-separated strings.
src/httk/web/model/config.py Adds config_name and compatibility fallback to _functions for function discovery.
src/httk/web/engine/site_engine.py Adds global config metadata + init bootstrap, publish/serve template overrides, and case-insensitive metadata lookups.
src/httk/web/api.py Exposes config_name through create_asgi_app, serve, and publish.
examples/modern/search_app/src/templates/search_results.html.j2 Adds modern search results fragment template.
examples/modern/search_app/src/templates/search_page.html.j2 Adds modern search page template wiring query + fragments.
examples/modern/search_app/src/templates/material_details.html.j2 Adds modern material-details fragment template.
examples/modern/search_app/src/templates/base_default.html.j2 Adds modern base layout for the search example.
examples/modern/search_app/src/functions/search.py Adds example search function over an in-memory dataset.
examples/modern/search_app/src/functions/init.py Initializes example dataset in global_data.
examples/modern/search_app/src/functions/details.py Adds example details lookup function.
examples/modern/search_app/src/content/index.md Adds modern page metadata wiring function injections.
examples/modern/search_app/serve.py Adds runnable serve script for the modern search example.
examples/modern/search_app/publish.py Adds runnable publish script for the modern search example.
examples/modern/search_app/README.md Documents the modern search example.
examples/modern/rst_site/src/templates/default.html.j2 Adds default template for modern RST site.
examples/modern/rst_site/src/templates/base_default.html.j2 Adds base layout for modern RST site.
examples/modern/rst_site/src/content/index.rst Adds modern RST front page content.
examples/modern/rst_site/src/content/about.rst Adds modern RST about page.
examples/modern/rst_site/serve.py Adds runnable serve script for modern RST site.
examples/modern/rst_site/publish.py Adds runnable publish script for modern RST site.
examples/modern/rst_site/README.md Documents the modern RST site example.
examples/modern/minimal/src/templates/default.html.j2 Adds minimal modern default template.
examples/modern/minimal/src/templates/base_default.html.j2 Adds minimal modern base layout.
examples/modern/minimal/src/content/index.md Adds minimal modern content example.
examples/modern/minimal/serve.py Adds runnable serve script for minimal example.
examples/modern/minimal/publish.py Adds runnable publish script for minimal example.
examples/modern/minimal/public/index.html Adds a prebuilt published HTML artifact for the minimal example.
examples/modern/minimal/README.md Documents the minimal modern example.
examples/modern/blog/src/templates/default.html.j2 Adds modern blog default template.
examples/modern/blog/src/templates/blog_post.html.j2 Adds modern blog post template.
examples/modern/blog/src/templates/blog_index.html.j2 Adds modern blog index template using pages().
examples/modern/blog/src/templates/blog_home.html.j2 Adds modern blog home template with latest posts.
examples/modern/blog/src/templates/base_default.html.j2 Adds modern blog base layout.
examples/modern/blog/src/functions/init.py Builds blog post lists at startup via global_data["pages"].
examples/modern/blog/src/content/index.md Adds modern blog home content.
examples/modern/blog/src/content/contact.md Adds modern blog contact content.
examples/modern/blog/src/content/blogposts/migration-notes.md Adds modern blog sample post content.
examples/modern/blog/src/content/blogposts/hello-modern.md Adds modern blog sample post content.
examples/modern/blog/src/content/blog.md Adds modern blog listing page content.
examples/modern/blog/serve.py Adds runnable serve script for modern blog.
examples/modern/blog/publish.py Adds runnable publish script for modern blog.
examples/modern/blog/README.md Documents the modern blog example.
examples/legacy/static_simple/src/templates/default.httkweb.html Adds legacy static-simple default template.
examples/legacy/static_simple/src/templates/base_default.httkweb.html Adds legacy static-simple base template demonstrating repeat/pages calls.
examples/legacy/static_simple/src/templates/bare.httkweb.html Adds legacy static-simple bare base template.
examples/legacy/static_simple/src/templates/404.httkweb.html Adds legacy static-simple 404 template using legacy conditional formatting.
examples/legacy/static_simple/src/static/resources/css/httkdemo.css Adds legacy CSS asset.
examples/legacy/static_simple/src/static/img/Example.png Adds legacy example image asset.
examples/legacy/static_simple/src/content/index.httkweb Adds legacy .httkweb content sample.
examples/legacy/static_simple/src/content/contact.httkweb Adds legacy .httkweb contact content.
examples/legacy/static_simple/src/content/bare.httkweb Adds legacy .httkweb bare page.
examples/legacy/static_simple/src/content/404.httkweb Adds legacy .httkweb 404 content.
examples/legacy/static_simple/src/config_dynamic.httkweb Adds legacy dynamic config example.
examples/legacy/static_simple/src/config.httkweb Adds legacy config example.
examples/legacy/static_simple/serve_legacy_static_simple.py Adds serve script for legacy static-simple example.
examples/legacy/static_simple/publish_legacy_static_simple.py Adds publish script for legacy static-simple example.
examples/legacy/search_app/src/templates/search_result.httkweb.html Adds legacy search results template.
examples/legacy/search_app/src/templates/search_page.httkweb.html Adds legacy search page template.
examples/legacy/search_app/src/templates/material_details.httkweb.html Adds legacy material details template.
examples/legacy/search_app/src/templates/default.httkweb.html Adds legacy search default template.
examples/legacy/search_app/src/templates/base_default.httkweb.html Adds legacy search base template.
examples/legacy/search_app/src/templates/base_app.httkweb.html Adds legacy search alternate base template.
examples/legacy/search_app/src/static/resources/css/httkdemo.css Adds legacy search CSS asset.
examples/legacy/search_app/src/static/img/Example.png Adds legacy search image asset.
examples/legacy/search_app/src/functions/search.py Adds legacy search function (depends on external legacy httk DB).
examples/legacy/search_app/src/functions/init.py Adds legacy search init function (legacy DB bootstrap).
examples/legacy/search_app/src/functions/details.py Adds legacy details function (legacy DB).
examples/legacy/search_app/src/content/index.httkweb Adds legacy search page metadata wiring function injections.
examples/legacy/search_app/src/content/404.httkweb Adds legacy search 404 content.
examples/legacy/search_app/src/config.httkweb Adds legacy search config.
examples/legacy/search_app/serve_legacy_search_app.py Adds serve script for legacy search example.
examples/legacy/search_app/publish_legacy_search_app.py Adds publish script for legacy search example.
examples/legacy/rst_templator/src/templates/default.templator.html Adds legacy web.py templator template (legacy baseline).
examples/legacy/rst_templator/src/templates/default.httkweb.html Adds legacy .httkweb.html default template.
examples/legacy/rst_templator/src/templates/base_default.templator.html Adds legacy web.py templator base template.
examples/legacy/rst_templator/src/templates/base_default.httkweb.html Adds legacy .httkweb.html base template.
examples/legacy/rst_templator/src/templates/bare.templator.html Adds legacy web.py templator bare template.
examples/legacy/rst_templator/src/templates/bare.httkweb.html Adds legacy .httkweb.html bare template.
examples/legacy/rst_templator/src/static/resources/css/httkdemo.css Adds legacy rst_templator CSS asset.
examples/legacy/rst_templator/src/static/img/Example.png Adds legacy rst_templator image asset.
examples/legacy/rst_templator/src/content/index.rst Adds legacy RST content sample.
examples/legacy/rst_templator/src/content/contact.rst Adds legacy contact content sample.
examples/legacy/rst_templator/src/content/bare.rst Adds legacy bare content sample.
examples/legacy/rst_templator/src/content/404.rst Adds legacy 404 content sample.
examples/legacy/rst_templator/src/config_dynamic.rst Adds legacy dynamic config in RST field-list form.
examples/legacy/rst_templator/src/config.rst Adds legacy config in RST field-list form.
examples/legacy/rst_templator/serve_legacy_rst_templator.py Adds serve script for legacy rst_templator example.
examples/legacy/rst_templator/publish_legacy_rst_templator.py Adds publish script for legacy rst_templator example.
examples/legacy/hello_world_app/src/templates/hello_world_result.httkweb.html Adds legacy hello-world result fragment template.
examples/legacy/hello_world_app/src/templates/default.httkweb.html Adds legacy hello-world default template including injected fragment.
examples/legacy/hello_world_app/src/templates/base_default.httkweb.html Adds legacy hello-world base template.
examples/legacy/hello_world_app/src/static/resources/css/httkdemo.css Adds legacy hello-world CSS asset.
examples/legacy/hello_world_app/src/static/img/Example.png Adds legacy hello-world image asset.
examples/legacy/hello_world_app/src/functions/init.py Adds legacy init function for hello-world app.
examples/legacy/hello_world_app/src/functions/hello_world.py Adds legacy hello-world function.
examples/legacy/hello_world_app/src/content/index.httkweb Adds legacy hello-world page metadata for function injection.
examples/legacy/hello_world_app/src/content/404.httkweb Adds legacy hello-world 404 content.
examples/legacy/hello_world_app/src/config.httkweb Adds legacy hello-world config.
examples/legacy/hello_world_app/serve_legacy_hello_world.py Adds serve script for legacy hello-world example.
examples/legacy/hello_world_app/publish_legacy_hello_world.py Adds publish script for legacy hello-world example.
examples/legacy/blog/src/templates/default.httkweb.html Adds legacy blog default template.
examples/legacy/blog/src/templates/blogpost.httkweb.html Adds legacy blog post template.
examples/legacy/blog/src/templates/blog.httkweb.html Adds legacy blog index template.
examples/legacy/blog/src/templates/base_default.httkweb.html Adds legacy blog base template.
examples/legacy/blog/src/templates/404.httkweb.html Adds legacy blog 404 template.
examples/legacy/blog/src/static/resources/css/httk.css Adds legacy blog CSS asset.
examples/legacy/blog/src/static/js/paginate.js Adds legacy blog pagination JS.
examples/legacy/blog/src/static/img/.gitignore Adds placeholder ignore file for blog images directory.
examples/legacy/blog/src/static/favicon.ico Adds legacy blog favicon asset.
examples/legacy/blog/src/functions/init.py Adds legacy blog init function building blog lists.
examples/legacy/blog/src/content/index.md Adds legacy blog home content with legacy-style front matter delimiters.
examples/legacy/blog/src/content/contact.md Adds legacy blog contact content.
examples/legacy/blog/src/content/blogposts/third_post.md Adds legacy blog sample post content.
examples/legacy/blog/src/content/blogposts/hello-everyone.md Adds legacy blog sample post content.
examples/legacy/blog/src/content/blogposts/another_post.md Adds legacy blog sample post content.
examples/legacy/blog/src/content/blog.md Adds legacy blog listing page content.
examples/legacy/blog/src/content/404.md Adds legacy blog 404 content.
examples/legacy/blog/src/config_dynamic.httkweb Adds legacy blog dynamic config example.
examples/legacy/blog/src/config.httkweb Adds legacy blog config example.
examples/legacy/blog/serve_legacy_blog.py Adds serve script for legacy blog example.
examples/legacy/blog/publish_legacy_blog.py Adds publish script for legacy blog example.
examples/legacy/README.md Adds top-level legacy examples index/notes.
examples/README.md Adds top-level examples index explaining modern vs legacy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +200 to 204
page_data = {
key: value
for key, value in metadata.items()
if isinstance(key, str) and key and not key.startswith("_") and not key.endswith("-function")
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

page_data filters out keys ending with "-function" in a case-sensitive way, but function injection now detects *-function keys case-insensitively. If metadata uses a different casing (e.g., Results-Function), it will incorrectly be exposed on page even though it’s treated as a function injection key elsewhere. Consider using a case-insensitive endswith here as well.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +17
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Minimal Modern Example</title>
</head>
<body>
<main>
<article>
<h1>Minimal Modern Example</h1>
<h1>Hello from httk-web</h1>
<p>This is the modern example using Jinja2 templates.</p>
</article>
</main>
</body>
</html> No newline at end of file
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a generated publish artifact rather than source for the example. Committing built HTML output can get stale and creates noise in diffs; consider removing it from version control and adding a .gitignore entry (or clearly documenting why this output is tracked).

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,3 @@
def execute(global_data, **kargs):
print("Debug: running website initalization function.")
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the debug message: "initalization" should be "initialization".

Suggested change
print("Debug: running website initalization function.")
print("Debug: running website initialization function.")

Copilot uses AI. Check for mistakes.
<th>#</th>
<th>Compound id</th>
<th>Formula</th>
<th>Anonumous formula</th>
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in column header: "Anonumous" should be "Anonymous".

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +26
if spec == "unquoted" or spec.startswith("unquoted:"):
return self._format_field(value, spec[len("unquoted::") :], quote=False)
if spec == "quote" or spec.startswith("quote:"):
return self._format_field(value, spec[len("quote::") :], quote=True)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unquoted: / quote: spec parsing slices using len("unquoted::") / len("quote::"), which drops one extra character for specs like unquoted:if:... (single colon) and breaks downstream spec handling (e.g., if: becomes f:). Use the correct prefix length (e.g., len("unquoted:")) or split on the first : to pass the remainder spec through unchanged.

Copilot uses AI. Check for mistakes.
Comment on lines +176 to +179
def vformat(self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> str:
self._current_args = args
self._current_kwargs = kwargs
return super().vformat(format_string, args, kwargs)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vformat() mutates self._current_args / self._current_kwargs but never restores the previous values. Because repeat/if call self.format(...) recursively, nested formatting will overwrite the outer context and can leak loop variables (e.g., item, index) into subsequent fields after the loop. Save/restore the prior state in vformat() (e.g., with a try/finally) so nested calls don’t affect the parent formatting context.

Copilot uses AI. Check for mistakes.
@rartino rartino merged commit 9d26e2f into main Mar 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants