Hello everyone, I’m evaluating Pinegrow as a solution for my current project, and looking at plugins landed me here.
I’ve built a media distribution platform (intended to be self-hosted, or hosted per-user as a service for those who choose to do so) with Django as a backend, and the last hurdle I have is how to let users create their own page templates. As such, I’m also in need of something that can handle Liquid / Jinja -type templates (Django templates are similar in syntax to those).
Off the top of my head here’s what I think this would entail, if one were to implement a template language plugin for an editor like this:
-
The functionality to both GET and POST templates from and to API endpoints (Git repo and custom API URL endpoints with auth parameters, at least)
-
The functionality to post-process elements back into template variables, which is basically an exercise in rendering a template in reverse. I.e., instead of a variable becoming an image as would be the case in the framework’s page renderer, an image would need to become a variable when the template is saved in Pinegrow if the user provides a template variable for the various image tag parameters.
-
To accomplish #2, some sort of context would need to be loaded with the editor instance that provides a list of available variables to choose. Since available variables are per-page on the server/framework side of things, this would probably be a nested list of objects. In my case since I have full control of the API with Django I could provide context with the API response that sends the initial template data to Pinegrow. For static site generators like Jekyll and Hugo without a database on the back end, it would probably entail creating a custom template tag that doesn’t get rendered in the final page, but rather holds the context data in the page markup for Pinegrow to use. Something like:
{% no_render %}
{
"home_page":
{
"{{ site.title }}": "your site title",
"{{ site.subtitle }}": "your site subtitle",
"{{ site.default_og_image }}": "your site default og meta image",
"{{ site.rss_feed }}": "your site rss URL",
"{{ blog.posts | limit:(number) | order -date }}": "your site last X number of blog posts",
...
},
"blog page":
{
"{{ blog.post.title }}": "your blog post page title",
"{{ blog.post.subtitle }}": "your blog post subtitle",
...
},
}
{% end no_render %}
Pinegrow could then pick up the json inside of the {% no_render %} tag as its list of context variables for a given page template type.
Optimally the context should be built programmatically on the framework’s side of things, of course. Could be a matter of providing a plugin that builds a swagger-type element that embeds the hidden markup in each page, with all possible core template variables for the static site generators and the view context from the database for the frameworks like Django that have a database backend.
- An option should exist to place template functions and filters, because some things need to be looped (in my case, complex page objects which support multiple entries in the CMS will need to be looped with the markup included to render each object, i.e. a list of article authors as in the example below). People will also want to use {% if %) / {% else %} conditional rendering tags in all likelihood, and provide custom filters on their template tags.
{% if blog.post.authors %}
{% for author in blog.post.authors %}
<div class="author-container">
<div class="author-overlay-style">
<span class="author-name"><a class="author-link" href="{{ site.url }}/authors/{{ author.id }}">{{ author.name }}</a></span>
<img class="author-avatar">{{ author.avatar.url }}</img>
</div>
</div>
{% endfor %}
{% endif %}
The irony is not lost on me that at some level of complexity this all becomes an exercise in putting the database into a GUI window’s dropdown boxes