Nesting two custom Liquid tags with advanced options

Is it possible to embed custom Liquid tags written in ruby ​​if one class has several optional tokens passed as parameters? This question is rather difficult to describe without providing an appropriate example. Please excuse me if this question seems like a too specific use case.

Given the following ruby ​​code, derived from Octopress (jekyll fork), which creates a custom Liquid tag for tag analysis.

# Title: Simple Image tag for Jekyll # Authors: Brandon Mathis http://brandonmathis.com # Felix SchΓ€fer, Frederic Hemberger # Description: Easily output images with optional class names, width, height, title and alt attributes # # Syntax {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %} # # Examples: # {% img /images/ninja.png Ninja Attack! %} # {% img left half http://site.com/images/ninja.png Ninja Attack! %} # {% img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %} # # Output: # <img src="/images/ninja.png"> # <img class="left half" src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!"> # <img class="left half" src="http://site.com/images/ninja.png" width="150" height="150" title="Ninja Attack!" alt="Ninja in attack posture"> # module Jekyll class ImageTag < Liquid::Tag @img = nil def initialize(tag_name, markup, tokens) attributes = ['class', 'src', 'width', 'height', 'title'] if markup =~ /(?<class>\S.*\s+)?(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?<width>\d+))?(?:\s+(?<height>\d+))?(?<title>\s+.+)?/i @img = attributes.reduce({}) { |img, attr| img[attr] = $~[attr].strip if $~[attr]; img } if /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/ =~ @img['title'] @img['title'] = title @img['alt'] = alt else @img['alt'] = @img['title'].gsub!(/"/, '&#34;') if @img['title'] end @img['class'].gsub!(/"/, '') if @img['class'] end super end def render(context) if @img "<img #{@img.collect {|k,v| "#{k}=\"#{v}\"" if v}.join(" ")}>" else "Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | \"title text\" [\"alt text\"]] %}" end end end end Liquid::Template.register_tag('img', Jekyll::ImageTag) 

What is the best way to create another custom tag to display the same functionality for the [ <img> ] element, but nested in the [ <figure> ] element and possibly display the alt description image or an additional token like [ <figcaption> ], which could potentially contain your own link? Or perhaps even a series of class names for an element that says whether to center or not.

In other words, I might want the output to be something like:

 <figure class=center> <img src="/contra.jpg" alt="One of the greatest nintendo games of all time"> <figcaption>Up Up Down Down Left Right Left Right BABA <a href="http://www.youtube.com/contramoves/">Watch on Youtube</a></figcaption> </figure> 

Am I mistaken in assuming that you can embed custom Liquid tags? I'm sure I can rewrite the existing code a second time and modify it a bit to handle the additional attribute for [ <figcaption> ], but this seems unnecessary against the DRY principles. And as it currently stands, I'm rather confused as to how I can explain the possible additional token, given that the existing class accepts optional tokens.

+4
source share
1 answer

I needed to create a Liquid Block, not a Liquid Tag. This solution allows, in principle, to fix other liquid tags and even other liquid blocks within the figure, which would be exact for the tag [ <figure> ].

Since Markdown does not currently support HTML5, this Liquid-based solution is a good compromise.

  # Example: # # {% fig This is my caption! http://site.com/link.html Link Caption %} # {% img center http://site.com/images/mylinks.png A collection of my favorite links %} # {% endfig %} # # Output: # # <figure class='center'> # <img class="center" src="http://site.com/images/mylinks.png" title="A collection of my favorite links" > # <figcaption>This is my caption!<a href='http://site.com/link.html'>Link Caption </a></figcaption> #</figure> # # module Jekyll class FigureTag < Liquid::Block include TemplateWrapper CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+)\s+(.+)/i Caption = /(\S[\S\s]*)/ def initialize(tag_name, markup, tokens) @title = nil @caption = nil if markup =~ CaptionUrl @caption = "\n\t\t<figcaption>#{$1}<a href='#{$2}'>#{$3}</a></figcaption>\n\t" elsif markup =~ Caption @caption = "\n\t\t<figcaption>#{$1}</figcaption>\n\t" end super end def render(context) output = super fig = super.join source = "\t<figure class='center'>\n\t\t" markdown = RDiscount.new(fig.lstrip).to_html[/<p>(.+)<\/p>/i] source += $1 source += @caption if @caption source += "</figure>" source = safe_wrap(source) source end end end Liquid::Template.register_tag('fig', Jekyll::FigureTag) 
+4
source

Source: https://habr.com/ru/post/1399822/


All Articles