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.

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.

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);
  }
}