No markdown parsing with kirbytags

Not sure if this is an issue or just me doing it the wrong way…

I want to use Kirbytags to offer a simple-to-use accordion within the content section:

kirbytext::$tags['accordion'] = array(
  'attr' => array(
    'title'
  ),
  'html' => function($tag) {
    switch ($tag->attr('accordion')) {
      case 'open':
        $markup  = '<section class="accordion"><header class="accordion-header">';
        $markup .= $tag->attr('title');
        $markup .= '</header><div class="accordion-content">';
        break;
      case 'close':
        $markup  = '</div></section>';
        break;
    }
    return $markup;
  }
);

In the content section (in the panel) this would be used like this:

(accordion: open title: My accordion title )
Lorem **fat impsum** dolor…
(accordion: close)

the problem is that Lorem **fat impsum** dolor… will not be outputted as HTML but as plaintext (including the asterisks). I think this is due to the opening HTML tags <section> and <div> – because closing them in (accordion: open…) solves the problem (but of course makes no sense).

Any ideas on this?

That’s a general problem with Markdown. HTML block tags prevent parsing of Markdown inside them.

For more complex tags like yours, it makes sense to implement a pre-filter instead. See the columns plugin for an example. It matches a set of two column tags (one opening and one closing one) and replaces them with custom HTML and the HTML representation of the Kirbytext inside the tags.

1 Like

Markdown inside html block tags is supported in parsedown extra (https://github.com/erusev/parsedown-extra/issues/14). If you enable Markdown Extra in your config.php

c::set('markdown.extra', true);

and change your tag code like this (i.e. add markdown="1" to your inner html tag):

<?php
kirbytext::$tags['accordion'] = array(
  'attr' => array(
    'title'
  ),
  'html' => function($tag) {
    switch ($tag->attr('accordion')) {
      case 'open':
        $markup  = '<section class="accordion"><header class="accordion-header" ';
        $markup .= $tag->attr('title');
        $markup .= '</header><div class="accordion-content" markdown="1">>';
        break;
      case 'close':
        $markup  = '</div></section>';
        break;
    }
    return $markup;
  }
);

your code should work.

3 Likes

Thank you for providing the two solutions!

For bigger projects I guess the plugin would be the more performant solution. But in my case I will go for markdown.extra – which is such a no-brainer!

Thanks

@a-v-l
I wrote a plugin what can help you with your problem.

With this plugin you can easy create tag with a begin and end tag, like…

(accordion title: My accordion title )
Lorem **fat impsum** dolor…
(/accordion)

kirbytext and markdown work in the tag body. As usage example, you can use the messagebox tag in the same plugin.

Here your plugin as example.

<?php
use at\fanninger\kirby\extension\webhelper\WebHelper;
require_once 'kirbycms-extension-webhelper-lib.php';

kirbytext::$pre[] = function($kirbytext, $value) {
  $offset = 0;
  $key = 'accordion';
  while ( ($block = WebHelper::getblock($key, $value, $offset)) !== false ) {
    $offset = $block[WebHelper::BLOCK_ARRAY_VALUE_ENDPOS];
    
    $attr = array();
    $attr['class'] = 'accordion-content';
    $content = \Html::tag("div", $block[WebHelper::BLOCK_ARRAY_VALUE_CONTENT], $attr);

    $attr = array();
    $attr['class'] = 'accordion';
    $attr['title'] = $block[WebHelper::BLOCK_ARRAY_VALUE_ATTRIBUTES]['title'];
    $block_new = \Html::tag("section", $content, $attr);

    $start = $block[WebHelper::BLOCK_ARRAY_VALUE_STARTPOS];
    $length = $block[WebHelper::BLOCK_ARRAY_VALUE_ENDPOS]-$block[WebHelper::BLOCK_ARRAY_VALUE_STARTPOS];	
    $value = substr_replace($value, $block_new, $start, $length);
  }
}