I recently discovered Grav and I am very happy that I finally found a clean and intuitive flat-file CMS. Thanks to the development team for creating this project!
In the roadmap of Grav 2 I can see that there is a plan of introducing Content Blocks and Widgets, but until we have them, I would like to know what is currently the best practice to reuse parts of content on different pages.
For example, I have a sidebar in which I would like to create some boxes which list links to external websites. In order to separate content and presentation, I created a page (pages/side_menus/default.md) which lists all the links in the YAML FrontMatter section.
Then I created a twig tamplate called āsidebar.html.twigā in the āpartialsā folder, with the following code:
{% set page = pages.find('/side_menus') %}
<section>
{% for menu in page.header.menus %}
{% if menu.active %}
<h1>{{ menu.title }}</h1>
<ul>
{% for link in menu.links %}
<li><a href="{{ link.url }}">{{ link.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
</section>
I could have written the links with markdowns in the content area of the .md file, but I find it more structured in a YAML hierarchy and easier to manipulate from the template file. It also allows me to activate/deactivate a menu easily.
This works, but I have several concerns:
I first wondered where I should put the links. I did not want to write them directly in the template files which in my opinion should not contain any content. Then I thought about creating a plugin, but it seems overkill for a simple list of linksā¦ I finally decided to put them in the āpagesā folder, although technically they are rather a block to include in pages than a page in itself. Is there a better place to put them?
From the admin interface, it is strange to go to āpagesā in order to edit these links. Additionally it is not possible to see on which pages those side menu will appear.
I find it strange to create a .md file without content (using only YAML inside the header). Isnāt it possible to just create a .yaml file?
In my understanding modular pages allow to create different areas within a page. This may look similar to what I want to do but I am more searching about a way to reuse blocks of HTML & content on different pages of the website.
I would be very happy to hear ideas and advice to achieve this in a better way.
Great question. Content reuse at all granularities is a pillar of CMSs IMO (Iāve done courses on CMS selection, been on selection panels, and written formal evaluations against business requirements in the past). Looking forward to seeing what content blocks bring myself.
Iām not going to do justice to your considered concerns just right now. But I did contemplate this in depth when I ported the Minimaxing theme with demo content a little while back. I used modulars as a hack in a similar way to you, so you might want to take a look for further inspiration. Specifically:
I havenāt spend too much time considering Admin UI implications as yet, since none of my clients use it (but they and I both want them to). Empty markdown sections are a little ugly, yes, but that doesnāt keep me awake at night. Conscious design or not, itās likely a trade-off of some sort.
Thank you for your reply. Your theme is a good example. It is reassuring to see that someone found a similar solution to what I didā¦
I also thought about gathering components inside a single folder, but when I first did it, they did not appear on the page. I just found out that I have to remove āvisible: falseā in the frontmaker (). According to the documentation this option should only affect the navigation, so I am not sure why it was preventing the block from showingā¦
Thank you also for sharing your thoughts (JSON data/catalogue API). I didnāt quite understand the JSON objects idea thoughā¦
I hope Grav 2 will allow creation of blocks in a separate folder that is not āpagesā, and that we will have a different page on the admin panel to manage them. I think it is important to clearly distinguish pages & block as they are quite different in nature.
Iām myself quite new to Grav, so my advice is probably not worth much. I bookmarked this thread to learn about the answers. And Iām glad I did. Many thanks to @hughbris for sharing those ideas and pointers! I will myself come back to that in a later project.
@mathmax: In your particular case I would argue that the sidebar configuration is part of the theme configuration, so I would consider making it accessible there with blueprints. I havenāt done something like this myself yet, though.
I would still love to learn more about the other options, though.
@Utis: Except maybe the āactiveā option in the hierarchy posted on my first post, the menus, titles and urls are all content, not configuration. So I am not sure how blueprints would be useful hereā¦ Could you explain more your idea?
Well, the way I understood you, they are part of a sidebar that is displayed on many pages. Maybe itās an edge case and you could argue that itās content. My feeling, however, is that itās something thatās comes with a theme, as part of itās page structure and is no more content than, say, a footer with links.
I havenāt really done this myself yet. But I mean adding something to your themeās blueprint like this:
form:
validation: loose
fields:
menus:
type: section
title: Sidebar
underline: true
fields:
active:
type: toggle
label: Active
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
links:
type: list
style: vertical
label: Links
fields:
title:
type: text
label: Title
url:
type: text
label: URL
And then, when you click in the admin panel on āThemesā ==> you have a form to edit those links.
@Utis: Itās a good idea to use a blueprint to allow adding/removing items from the admin panel. I havenāt yet played with blueprints either, and I am not really sure what would be the advantages to store the data at the theme level vs at the page level. My feeling is that, in this case, it is better to create a page blueprint rather than editing the configuration of the theme. You took the example of the footer, but I would also consider it as content. If you look at grav-skeleton-open-publishing-space-site, you will see that they created a āfooterā page:
Now if I create side_menus.yaml, I can target my side_menu component and reproduce the same hierarchy as posted on my first post (note that I need to add prefix the field names for your file to work). The blueprint helps editing from the admin panel, but doesnāt change the way I structured my files.
Later, I may want to move the āactiveā options to a separate blueprint to be able to enable menus only on certain pages, while still having the links stored in a single place.
Thinking about this some more, I think I eventually agree: Itās maybe a better compromise to put the data in pages and maybe create a blueprint to edit them in forms.
But for me, in this case, itās more a question of exposing a predictable interface to the end user. (In the end itās always about interface, inside itās just numbers at memory adresses.) IMHO, the concept of āthemesā in the CMS world sits in an uneasy place anyways and is neither here nor there: Themes define not only appearance and viewer interaction, but also content structure and logic; and a site likely breaks when switching to another theme. Components are conceptually probably right in between āthemeā and āpageā (content). Personally, the fact that a component disappears when switching to another theme makes me inclined to put them more on the theme side.
That being said, in practise, for end users, making the data configurable in the themeās config panel is probably far too hidden and difficult to find. Maybe if itās just a single component, Iād still consider doing it. But if thereās several of them, creating pages in a components folder might indeed be better, especially if these provide forms. Itās not ideal, though, I can see end users looking at the pages panel, wondering whether and when they created these āpagesā.
Ideally, components would have their own section in the admin panel right between āPagesā and āThemesā. With their data being stored in `user/componentsā. Maybe that can be achieved with a plugin?
(Donāt know what you meant with āprefix the field namesā; it worked for me.)
Yes, exactly. I agree that components are kind of āin betweenā theme and pages. Pages should be stable when switching from one theme to another, whereas components (or blocks) may change. I also think they should appear in a different section on the admin panel. For now, the best i could do is to gather them inside a āblocksā folder which separates them a bit from normal pages although they still appear under āpagesā in the admin panel. I expect Grav2 to improve thisā¦ I believe that components are, like bricks, the basics of a well designed project.
Btw, i like how Magento handles components. Basically, you can define default components, override them per theme, and reference them through layout files (XML in the case of Magento). Layout files are part of a theme, but are not exactly templates: their role is just to bind sets of pages to various components, describing where they should be positioned on the pages.
By prefix, i mean adding āheader.menus.[ā¦]ā to the field names of the blueprints. Sorry i am on my mobile, so i canāt test it again now. Without prefix, you can fill the form in the admin panel, but you shouldnāt be able to save the data. Please give it a try.