-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rendering from data (not individual files) #72
Comments
I'm not sure I understand what you mean. Could you provide a bit more details? Anyway, I'm pretty sure it will be easier if you use my stalled PR #65 whose goals were both to allow the reloader to rebuild only the needed pages and to be much easier to subclass for specific needs. |
Glancing at your pull request, it looks like I might be able to achieve what I'm looking for by subclassing the Builder, SourceManager, and Reloader, will try that sometime soon. Clarifying my request somewhat, fundamentally staticjinja operates on a directory of files, it processes each file one by one according to some rule allowing modification of how each specific file is rendered/its context. I'd like to pass an arbitrary list of elements with the following attributes:
These add_render rules wouldn't be built until site.render() is executed (they'd get rendered with everything else and rebuilt automatically). Right now it seems like I would need to have files 0-9 and set a render rule which seems silly. My underlying data shouldn't need to be represented by files. If I changed |
@u8sand Did you ever find a solution for this? I have a similar requirement |
@Fredericco72 Basically I did not come up with any good solution but the project I was using this for is long done. In retrospect, staticjinja is simple and good for something specific -- if your use-case is not that, you're likely better off just using jinja2 directly. If your use case is along the lines of using a database to generate content and rendering cascading changes #65 was on the right track. If I was going to use something like this again I would likely just use makefile, potentially generating one with python or doing it all in Makefile. Just a sketch of what it might look like: # jinja2-cli from https://github.com/mattrobenolt/jinja2-cli
TEMPLATE_COMPILER = jinja2
TEMPLATES=$(shell find templates -type f -exec sh -c 'realpath --relative-to=templates {}' \;)
DIST=$(foreach template, $(TEMPLATES), build/$(template))
# rule to build a template
build/%: templates/%
mkdir -p $(shell dirname $@) && $(TEMPLATE_COMPILER) $^ context.json > $@
# trigger all template builds
build: $(DIST)
# auto-remake support https://stackoverflow.com/questions/7539563/is-there-a-smarter-alternative-to-watch-make
WATCHMAKE=build
watch:
while true; do \
make $(WATCHMAKE); \
inotifywait -qre close_write .; \
done
# additional constraints -- i.e. load data from db
records.json:
mysql 'select * from records' > $@
|
Finally looking through these ancient issues trying to close them out... At this point I believe that you could accomplish this, by using a custom rendering function. See an example at e6b7ef6. You could use a regex to match against I agree however that I think this use case is a bit too complicated for |
This was brought back up as a feature request in #124. I do see the usefulness of this feature personally. And, it seems as though there is a bit of demand, since two people in the last year out of the ~100 current dependents (according to GitHub, probably a slight underestimate?) have asked for it. So, I'm considering how to support this. However, I also think it's very valuable how simple staticjinja is right now, so if it's going to happen, this feature had better be pretty streamlined. At this point, the design requirements I'm thinking of are:
I'll reopen this Issue as I experiment with APIs, and comment here with any PRs I propose, and would love some feedback. |
I managed to hack together a solution. Here's a build.py. #!/usr/bin/env python3
import os
import re
from staticjinja.staticjinja import Site, _ensure_dir
class Site(Site):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.extras = {}
@property
def templates(self):
yield from super().templates
for name, template_name in self.extras.items():
template = self.get_template(template_name)
# the template name is what is used for the file name
template.name = name
yield template
def add_extra(self, name, template_name, context):
if name in self.extras:
raise ValueError(name + " is already registered")
self.extras[name] = template_name
# partial copy of Site.render_template
def render_extra_page(site, template, **context):
filepath = os.path.join(site.outpath, name)
_ensure_dir(filepath)
template.stream(**context).dump(filepath, self.encoding)
file_pattern = "^{}$".format(re.escape(name))
self.rules.insert(0, (file_pattern, render_extra_page))
self.contexts.insert(0, (file_pattern, context))
def main():
site = Site.make_site()
# add extra pages individually
site.add_extra("hello.html", "_layout.j2", {"message": "Hello!"})
site.add_extra("child/index.html", "_layout.j2", {"message": "This is a child index page."})
site.render()
if __name__ == "__main__":
main() |
+1 for this feature request. I'll give @killjoy1221's implementation a try for now, but I also wanted to suggest an API option: Rendering multiple result pages from the same template is tied directly to the data source (you need multiple datasets to do it in the first place). Therefore the natural place for configuring it in the existing API is the
Both of these can be solved with a small change to the
This change should be fully backwards compatibile and keeps the declarative API intact. |
I had a use-case where I created a static webpage to display information available in a database. In particular it required me to create my own render function/loop:
Would there be a way to register these pages with staticjinja such that they would be regenerated if the underlying
_post.html
page was changed. Perhaps even a "changed" hook could be exposed so that the underlying data could report changes and get it regenerated.I'm specifically interested if there is already a way to do this, else I may fork and contribute a solution if you're interested.
The text was updated successfully, but these errors were encountered: