K.Q. Dreger
K.Q. Dreger

Reputation: 192

Add URL field to Jekyll post yaml data

I want to programmatically append a single-line of YAML front data to all the source _posts files.

Background: I currently have a Jekyll-powered website that generates its URLs with the following plugin:

require "Date"

module Jekyll
  class PermalinkRewriter < Generator
    safe true
    priority :low

    def generate(site)
      # Until Jekyll allows me to use :slug, I have to resort to this
      site.posts.each do |item|
        day_of_year = item.date.yday.to_s
        if item.date.yday < 10
          day_of_year = '00'+item.date.yday.to_s
        elsif item.date.yday < 100
          day_of_year = '0'+item.date.yday.to_s
        end

        item.data['permalink'] = '/archives/' + item.date.strftime('%g') + day_of_year + '-' + item.slug + '.html'
        end
      end
    end
  end
end

All this does is generate a URL like /archives/12001-post-title.html, which is the two-digit year (2012), followed by the day of the year on which the post was written (in this case, January 1st).

(Aside: I like this because it essentially creates a UID for every Jekyll post, which can then be sorted by name in the generated _site folder and end up in chronological order).

However, now I want to change the URL scheme for new posts I write, but I don't want this to break all my existing URLs, when the site is generated. So, I need a way to loop through my source _posts folder and append the plugin-generated ULR to each post's YAML data, with the URL: front matter.

I'm at a loss of how to do this. I know how to append lines to a text file with Ruby, but how do I do that for all my _posts files AND have that line contain the URL that would be generated by the plugin?

Upvotes: 1

Views: 611

Answers (1)

David Jacquel
David Jacquel

Reputation: 52829

Et voilà ! Tested on Jekyll 2.2.0

module Jekyll
  class PermalinkRewriter < Generator
    safe true
    priority :low

    def generate(site)

      @site = site
      site.posts.each do |item|
        if not item.data['permalink']

          # complete string from 1 to 999 with leading zeros (0)
          # 1 -> 001 - 20 -> 020
          day_of_year  = item.date.yday.to_s.rjust(3, '0')
          file_name    = item.date.strftime('%g') + day_of_year + '-' + item.slug + '.html'
          permalink    = '/archives/' + file_name

          item.data['permalink'] = permalink

          # get post's datas
          post_path    = item.containing_dir(@site.source, "")
          full_path    = File.join(post_path, item.name)
          file_yaml    = item.data.to_yaml
          file_content = item.content

          # rewrites the original post with the new Yaml Front Matter and content
          # writes 'in stone !'
          File.open(full_path, 'w') do |f|
            f.puts file_yaml
            f.puts '---'
            f.puts "\n\n"
            f.puts file_content
          end

          Jekyll.logger.info "Added permalink " + permalink + " to post " + item.name
        end
      end
    end
  end
end

Upvotes: 2

Related Questions