Kirbytext tags and HTML structure

Yup, it’s only on a specific template. So if I understand it well, you are suggesting to add the closing/opening wrapper to the tag code? If that is the case, I think I might encounter the problem @AugustMiller describes above:

I’m currently exploring the following (combined) approach:

1- The custom tag prints the html with a couple of comments

<!-- kirby-filter:wrapper-close -->
<div class="media-block"></div>
<!-- kirby-filter:wrapper-open -->

2- Using a post filter I check that we’re on the particular template and then replace those comments with closing/opening wrappers. I also add the initial wrapper with this filter (instead of doing it in the template).

Still not convinced this is the best solution, but it seems to work.

Call it crazy (and overkill), but this might be a nice solution.

For a page that has a lot of content flowed together into some kind of compelling text and image experience, you might set up a blueprint that allows pages of just a couple types:

    - text
    - media

Then, you add subpages containing the text and media. They can be made visible and sorted with Kirby’s built-in page ordering.

Alternatively, you could leave them invisible, and order them (or omit them entirely) by creating a structure field on the parent page:

  label: Story Builder
  type: structure
      label: Name
      type: text
      label: Section
      type: select
      options: children
  entry: >

Then, in your template, you’d iterate over those sections of text and media, figure out what the faux-page’s intendedTemplate is, and render a different block.

You might also create a page method that is able to extract just the text and images from the subpages (based on the implementation you chose, above) so they can be output as a concatenated stream.

This is an evolving thought, and an awesome original question.

I did something similar with Wordpress, ACF and the flexible content field for ScriptEd about a year ago (It was all handled by Elliot’s ingenious form builder, and a lot of partials— we were dealing with about 8 different content types that needed to be flowed together or composed to create their homepage and mission page).

Edit: This isn’t a strictly markdown solution, though.

Edit 2: What I really like about this is that you could pretty easily fetch just media ($page->sections('media')) or just text ($page->sections('text')) through custom methods…

Wow! That’s a really creative solution that opens up some interesting possibilities! I think it can be very helpful in some situations. Thanks for sharing!

But what I need is something way simpler. To recap, the solution should:

  • Work out of the box without modifying the Markdown file in the example
  • Produce the same exact HTML as in the example
  • Be completely unobtrusive, invisible to the client/editor
  • Not rely on CSS or JS
  • Bonus: should not be a hack. The kirbytext post-filter approach produces what I need, but I still feel it’s a dirty solution.

Why don’t you add the opening and closing wrapper tags into the kirbytext tag only if the page uses a specific template?

This solution remembers me of Crafts’s matrix field type which is a great if you want to give editors powerful predefined styling options and stay in control over the markup/styling at the same time.

You can use pages in a very flexible way, however, sometimes this doesn’t seem to be the most intuitive way (at least if you aren’t experienced with Kirby).

Because I need to close the wrapper before rendering my kirbytext tag and if I do so inside the tag, I’ll run into problems when the text is passed through Kirby’s HTML method that attempts to produce valid HTML because it will find closing div tags that do not match any opening tags.

What I’m currently doing is something similar that works but that doesn’t feel very solid (and looks like a dirty hack to me):

I briefly tested this and couldn’t find such a rendering problem. The only problem is if the media block is at the end and not followed by any more text. But that will be the same with your filter method, I guess.

The filter method could solve that problem by checking for empty wrapper divs and removing them. But I’m still not convinced. I don’t prefer my method over yours, I just feel both are hacks. I think tags should have a single responsibility and shouldn’t be aware of or modify their surrounding context.

I’d still do this using CSS, for example like this:

.media-block {
  height: 300px;
.media-block__content {
  position: absolute;
  left: 0;
  width: 100%;
  height: 300px;
  background-color: #ccc;

No calc, no negative margins. Only downside is that you specifically need to set the height of the media-block.

Another solution that doesn’t require specifying the height would be to directly apply the css rules of the wrapper class to all kirbytext elements except the media block. If you add another class like “.editor-content” it shouldn’t even get too unwieldy:

.editor-content > * {
   max-width: 1200px;
   margin-right: auto;
   margin-left: auto;
   padding-right: 4%;
   padding-left: 8%;
.media-block {
  width: 100%;
  height: 300px;
  background-color: #ccc;
  .editor-content > & {
     max-width: 100%;
1 Like

Sorry, but I don’t see any benefit to a CSS approach. On the contrary, it introduces a lot of complexity.

What I’m trying to solve is not a layout problem. What I need is a way to tell Kirby how and when to print some HTML. That’s it. If I just had to write plain HTML for the site (without processing any Markdown through Kirby) the solution would have been straightforward since I would have just needed to write the HTML code on my example post.html

Thanks for your suggestion anyway!

That’s what I feel about any non-CSS solution posted so far, while the CSS is really quite straightforward and predictable. But I’m not going to try to convince you, your current “hack” is probably the way to go if you don’t want to use CSS.

I don’t like the hack either. As I said before, what I’m looking for is how to do something with Kirby without working around it (CSS solution) or using some ugly hacky code (post-filter solution).

The thing is that the only reason you want to close & reopen the wrapper, IS the Kirbytag. So from my point of view it makes total sense to handle everything from within it - where else? I think it would worth it trying to get around the HTML method’s requirement for “complete” HTML.

Just out of interest, what would your “non-hacky dreamcode” be to handle this case? Might be interesting for Bastian :wink:


Magic! Haha. I don’t know. I was hoping there was a feature in Kirby I wasn’t aware of…

I wonder how @bastianallgeier would handle this problem.

The more I think about it, the more obvious it gets to me that it actually IS a layout problem.

Just think about why you’re actually using the wrapper div. It’s not because it’s really necessary or good HTML. (On the contrary, it’s actually highly non-semantic and groups elements for strictly visual purposes.) It’s a layout helper that we all use because it makes dealing with outer margins and max-widths easier.

In this case, however, it completely defeats that purpose: It’s not making your life easier anymore, but much more complicated because you have to deal with an exception to the rule that you introduced yourself.

So, while this might not change your view on it, if it was me, I’d get rid of the div.wrapper for all user generated content and apply its narrowing rules directly, using something like the 2nd CSS technique I posted earlier.

This way it’s easy to handle exceptions and you can decide on a per-template basis whether you want to include the “narrow content” class or not.


Alright, I buy your reasoning. It is a layout problem. :smile:

What actually bothers me is that I can’t solve it with what I think is the simplest and most straightforward approach. An approach that only requires a single <div> element, no complex CSS to override/workaround and that is doable in plain HTML. But I can’t produce the code in Kirby because there is a “blurry area” that I can’t easily control between the raw content and the HTML output.

Of course I’d love to find THE ideal solution but I realize that both, the CSS and the post-filter approaches are good (enough?) although they require some compromises and add complexity to the code.

Ok, last idea:

.wrapper can be a full-width container. It defines the absolute maximum width of the area where its content can expand to. Images, figure tags, etc. are allowed to occupy the full width of this space.

Then, any p inside it is given a different max-width (say, 66%, or 45em), and margin: 0 auto 1em auto to balance the remainder of the space to its left and right.

This, of course, means that you have to duplicate CSS to synchronize the widths of your paragraphs and whatever other columnar layout you’re using.

Edit: Really, it might be more like .wrapper > *:not(.media) { ... }, instead of .wrapper > p { ... }, because you may have a mixed bag of typographic elements inside the wrapper/content container…

1 Like

This makes a lot of sense and looks like the simplest possible CSS-based solution. I like it! I’ll give it a try and let you know how it goes.

This has been an amazing discussion! Thanks everyone! @AugustMiller, @Malvese, @diondiondion, @texnixe, @Luke, @twirx


I’ve achieved similar layouts in the past with what I consider is very simple CSS. If the “.wrapper” part is not extremely necessary, maybe this will help:

In my case, it all comes down to the type of CSS framework I work with, which is Kube, by the way. The grid component it packs is extremely flexible and it has many helpers that, in my opinion, work fantastically even with most irregular layout ideas I come up with.

Anyway, here’s a sample of a longform-type article layout made with pure kirbytext (still a WIP, don’t judge):


It’s quite responsive. The design itself contains a visual grid, so that makes it easier to notice how everything works.

Here’s another test that resembles your desired layout:


Basically, I’m styling each block element with simple CSS, inside a 100% container with a 1200px grid.

The quotes sections work with a kirbytext tag like this:

Guadalajara en sus inicios fue para mi como un sueño lúcido, después de una pequeña visita que se alargó a dos semanas, pues enamore de la ciudad y su poder en desarrollo, volví a Querétaro solo a preparar una venta de mis obras/toquín con mi banda y regrese corriendo.

(quote: Lo más hermoso y obvio de imaginar es que es gratis, <span>materializar tus proyectos e ideas...</span>)

Desde el primer día que llegué, conocí a la gente indicada, estoy segura de que la ciudad me llamó y la ciudad me abrazó, he participado haciendo murales, tocando en diversos sitios y uniéndome con gente muy talentosa que busca lo mismo que yo, crear y evolucionar lo que le ofrecemos al mundo, divirtiéndonos y trabajando con el corazón, to be true.

Take a look at the template and less file.

Again, hope this helps, feel free to grab code from the CSS file.

P.S. I didn’t really read the whole thread, so, sorry if this was already discussed before. :stuck_out_tongue: