Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you access page properties (YAML front matter) within a converter plugin

I'm writing a converter plugin for Jekyll and need access to some of the page header (YAML front matter) properties. Only the content is passed to the main converter method and does not seem possible to access the context.

Example:

module Jekyll
  class UpcaseConverter < Converter
    safe true
    priority :low

    def matches(ext)
      ext =~ /^\.upcase$/i
    end

    def output_ext(ext)
      ".html"
    end

    def convert(content)

      ###########
      #
      # Its here that I need access to the content page header data 
      #
      # 
      ###########

      content.upcase
    end
  end
end

Any ideas how I can access the page header data within a converter plugin?

like image 827
pipe-devnull Avatar asked Jul 03 '13 15:07

pipe-devnull


People also ask

How do you use YAML front matter?

YAML frontmatters can be defined at the beginning of a file, by starting on the first line with three dashes ( --- ) and ending the frontmatter either with three dashes or three dots (the former variant is more common). They contain valid YAML and can be used to define arbitrary variables.

What is YAML front matter PHP?

YFM is an optional section of valid YAML that is placed at the top of a page and is used for maintaining metadata for the page and its contents.

What is front matter Markdown?

Frontmatter is a way to identify metadata in Markdown files. Metadata can literally be anything you want it to be, but often it's used for data elements your page needs and you don't want to show directly. Some examples of common metadata are: Title of the post. Description for SEO purposes.

What is front matter HTML?

Front matter is a snippet of YAML placed between two triple-dashed lines at the start of a file. You can use front matter to set variables for the page: --- my_number: 5 --- You can call front matter variables in Liquid using the page variable.


2 Answers

Based on the Jekyll source code, it is not possible to retrieve the YAML front matter in a converter.

I see two solutions that could work depending on your situation.

  1. Your file extension could be descriptive enough to provide the information you would have included in the front matter. It looks like the Converter plugin was designed to be this basic.

  2. If modifying Jekyll is an option, you could change the Convertible.transform method to send the front matter to Converter.convert. The Converters that come with Jekyll would have to be modified as well. Fork it on GitHub and see if others like the idea. Here's where to start: https://github.com/mojombo/jekyll/blob/cb1a2d1818770ca5088818a73860198b8ccca27a/lib/jekyll/convertible.rb#L49

Good luck.

like image 115
Michael Gassman Avatar answered Nov 15 '22 07:11

Michael Gassman


devnull, I ran into a similar situation and I figured a way of doing it.

In the converter, I registered a pre-render hook to pull YAML into a variable, so that in the actual convert method, I have access to the info I just pulled. Also, another post_render hook is needed to remove that piece of info since this should be a per-post data.

A side note. I found that the convert will be called twice, once for use in the html <meta> tag, once for the actual content. The hook will be only invoked for the second case, not the first. You may need to guard you convert function.

Another side note. I think having YAML in the converter is not unreasonable. Just like in pandoc where you can specify bibliography file in the YAML section and do other fine tuning, people should be given freedom to customize a single post using YAML, too.

  def initialize(config)
    super(config)

    Jekyll::Hooks.register :posts, :pre_render do |post|
      if matches(post.data["ext"])
        # extract per post metadata, including those in YAML
        @myconfig["meta"] = post.data

        # you may need the path to the post: post.path
      end
    end 

    Jekyll::Hooks.register :posts, :post_render do |post|
      if matches(post.data["ext"])
        # remove per post metadata
        @myconfig.delete("meta")
      end
    end
  end 

  def convert(content) 
    return content unless @myconfig["meta"]

    # actual conversion goes here
  end
like image 33
Steinway Wu Avatar answered Nov 15 '22 08:11

Steinway Wu