Kirbytext tags and HTML structure

I can’t quite figure out the right/best solution to produce the following HTML structure with Kirbytext.

Given the markdown file on the left, I want to achieve the layout on the right. In order to do so I will need to close the .wrapper div before the .media-block item and open a new one afterwards.

The template looks like this:

<div class="wrapper">
    <?php echo $post->text()->kirbytext() ?>
</div>

I don’t want the Kirbytext tag to open and close the .wrapper div because I may need to use it in other places of my website where there is no wrapper div at all. I also want to avoid CSS-based solutions (using negative margins, …).

Any ideas on how to solve this?

You could use a solution similar to the columns plugin. Just modify it to be “wrapper”, or even use it as is.

(columns...)

## TITLE
PARAGRAPH

(...columns)

(media-block: image.jpg)

(columns...)

## TITLE
PARAGRAPH

(...columns)

Thanks @Luke but I would like to keep the markdown file untouched (the editors shouldn’t worry about html output) and do the markup work behind the scenes.

In that case, perhaps a javascript/jquery solution that amends the DOM, adding the wrappers after the fact. When it detects the media block, it closes the wrapper, and then reopens it to continue content.

Negative margin? You could just style a figure tag to extend beyond the main container bounds.

The JS solution won’t work: the layout will break if JS is disabled or if the script fails to load. It would also cause new layout calculation and repaints and thus will hurt the page performance. Thanks for the ideas @Luke, I’m sure we’ll find to the right solution. :smile:

@AugustMiller as I said, I want to avoid CSS solutions. There are some things we can’t accomplish with CSS alone, like aligning the block to an outer grid.

Ha! Typed this while lying in bed, half asleep. Sorry!

Haha! No worries. Please, feel free to share any ideas you may have! :wink:

Only one leftover from my original list:

4. Explode the text string and work from the resulting array

I think another approach could be to use a Kirbytext pre filter. I might be able to prepend the closing div to the media-block and append the new one immediately after it. Not sure if this is the cleanest solution though.

Depending on whether you’re creating mismatched tags (expecting them to be opened or closed outside the generated/parsed block), you may run in to problems with filters when the text is passed through Kirby’s html method— it attempts to close tags and make valid HTML of the passed text.

Maybe this happens pre-filter, though?

You’re right. The only way to prevent those problems is to always open AND close the wrapper divs inside the filter. And it’s also a safer and cleaner approach I think.

How do I find a kirbytext tag in the raw markdown string inside the pre filter? Is there an existing Kirby(text) method or should I use a regexp?

Can I ask what is the reason you want to avoid negative margins?
Perhaps you could use calc() along with negative margins to give your media-block the appropriate width.

Closing and re-opening the wrapper div can bring more problems imho. Like, if you need any kind of margin after the content, you’ll need to target each part individually so you need additional classes…

1 Like

The reason I want to avoid negative margins is because it’s hard to control. In some situations it may require a lot of math. It also means that I always need to be aware of the context where the module (.media-block) will be rendered in order to position it and thus it adds complexity to the code.

It’s also sometimes impossible to calculate the module position when everything has relative sizes and spacings. Take this example:

.wrapper {
   max-width: 1200px;
   margin-right: auto;
   margin-left: auto;
   padding-right: 4%;
   padding-left: 8%;
}

.media-block {
   width: 100vw;
   margin-left: -???;
}

How do you make the .media-block span the whole viewport width?

This is what I’ve done in such a case:

.media-block {
  margin-left: calc(-1 * (100vw - 100%) / 2);
  width: calc(100vw);
}
.wrapper {
  (your styles here…)
  position: relative;
}

In Safari < 8, vw units work, but not inside calc(). So I use calc(100vw) instead of 100vw, otherwise Safari would resize the element to 100vw, but not apply the negative margin. TL;DR, the above styles do nothing in Safari < 8 and the image stays in the wrapper…

You also have to add this to avoid an horizontal scrollbar in some browsers:

body {
  overflow-x: hidden;
}

You can see it in action on Le Figaro Madame (not a Kirby site :wink: ). All the elements sticking out of the main column use it.

What a beautiful website!

I see your point, but as I said before a CSS solution adds a lot of complexity and introduces new problems (browser support, scrollbars, …). Also, your solution for full-width images doesn’t seem to work with my example (note that the left padding is different than the right one): http://codepen.io/danielguillan/pen/waGeMp

I think the HTML approach is simpler, cleaner and completely straightforward as it doesn’t require any CSS. The hard part is injecting the wrapper divs with Kirby.

Thank you very much for your help!

Yep, to avoid this padding issue you’d probably need a second wrapper:

.wrapper {
   max-width: 1200px;
   margin-right: auto;
   margin-left: auto;
   position:relative;
}
.wrapper-inner {
   padding-right: 4%;
   padding-left: 8%;
}

But I agree that with a complex layout, an html approach is more solid.

If you need to split the wrapper only in a particular template, could you add a test in the Kirbytext code? It seems to be a custom Kirbytext tag already.