Neovov
Neovov

Reputation: 349

Issue writing a jekyll plugin for custom tags having nested tags

I'm trying to code a jekyll plugin to add some tags to handle some tabbed blocks since my website will have a lot of pages having this kind of blocks. I want to edit it easily in markdown.

I'm trying to use this liquid code :

{% tabs %}
  {% tab tab-1 %}
    Content of tab #1
  {% endtab %}

  {% tab tab-2 %}
    Content of tab #2
  {% endtab %}

  {% tab tab-3 %}
    Content of tab #3
  {% endtab %}
{% endtabs %}

Giving this HTML code:

<div class="tab-content">
  <div class="tab-pane" id="tab-1">
    Content of tab #1
  </div>
  <div class="tab-pane" id="tab-2">
    Content of tab #2
  </div>
  <div class="tab-pane" id="tab-3">
    Content of tab #3
  </div>
</div>

Here is my plugin:

module Tags
    class TabsBlock < Liquid::Block
        def render(context)
            '<div class="tab-content">' + super + "</div>"
        end
    end

    class TabBlock < Liquid::Block
        def initialize(tag_name, tab, tokens)
            super
            @tab = tab.strip
        end

        def render(context)
            return "" if @tab.empty?

            site      = context.registers[:site]
            converter = site.getConverterImpl(Jekyll::Converters::Markdown)

            content = super.strip
            content = converter.convert(content)

            '<div id="' + @tab + '" class="tab-pane">' + content + "</div>"
        end
    end
end

Liquid::Template.register_tag("tabs", Tags::TabsBlock)
Liquid::Template.register_tag("tab",  Tags::TabBlock)

When I try, the markup is not correct. Only the first tab's markup is what I am expecting, the other tabs are passed through the code highlighter and I get:

<div class="highlight">
  <pre><code class="text language-text" data-lang="text">&lt;div id=&quot;tab-1&quot; class=&quot;tab-pane&quot;&gt;&lt;p&gt;Content of tab #1&lt;/p&gt;</code></pre>
</div>

I have no idea why and I don't know much in Ruby/Liquid to handle it by myself :). Any idea?

Thanks!

Upvotes: 2

Views: 1072

Answers (2)

ercfre
ercfre

Reputation: 193

This is fantastic. For anyone who comes across this:

change:

getConverterImpl

to

find_converter_instance

Upvotes: 1

Neovov
Neovov

Reputation: 349

I don't know why, but Jekyll or Liquid considered that, given the indentation, it was some code to highlitght.

I resolved this by stripping again the markdown converted code to remove line breaks and by removing some indentation:

class TabBlock < Liquid::Block
    def initialize(tag_name, tab, tokens)
        super
        @tab = tab.strip
    end

    def render(context)
        return "" if @tab.empty?

        site      = context.registers[:site]
        converter = site.getConverterImpl(Jekyll::Converters::Markdown)

        lines = super.rstrip.split(/\r\n|\r|\n/).select { |line| line.size > 0 }
        indentation = lines.map do |line|
            match = line.match(/^(\s+)[^\s]+/)
        match ? match[1].size : 0
        end
        indentation = indentation.min

        content = indentation ? super.gsub(/^#{' |\t' * indentation}/, '') : super
        content = converter.convert(content)
        content = content.strip # Strip again to avoid "\n"

        '<div id="' + @tab + '" class="tab-pane">' + content + "</div>"
    end
end

Upvotes: 2

Related Questions