What are the steps to getting this 'custom' permalink scheme in Jekyll? - ruby

I'm writing a Jekyll setup and I'd like to get my posts to have a permalink in the form: /2013/jan/something-something-in-january. I understand that it is impossible with vanilla permalinks to:
get the :month to be in text form or
get the :title to be dash delimited
I remember reading somewhere that I could achieve this by writing a plugin, but I'm not sure how. How can I do this?

I created a generator plugin:
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|
item.data['permalink'] = '/' + item.slug + '/'
end
end
end
end

Related

In Jekyll, how can I programmatically modify permalinks for pages?

In a Jekyll site with many pages (not blog posts), I want to tweak the permalink of each page programatically. I tried a Generator plugin, something like:
module MySite
class MySiteGenerator < Jekyll::Generator
def generate(site)
site.pages.each do |page|
page.data['permalink'] = '/foo' + page.url
# real world manipulation of course more complicated
end
end
end
end
But although this would run and set the page.data['permalink'] field, the output was still the same.
Is there something I'm doing wrong, or is there a different way entirely of doing this? Thanks!
It can be easier to override the page class with something like this :
module Jekyll
class Page
alias orig_permalink permalink
def permalink
permalink = orig_permalink
newPermalink = "foo/#{permalink}"
end
end
end
Not tested.

Preprocessing markup files in jekyll

I would like to write a preprocessor that operates on a range of markup languages before they're processed into HTML by Jekyll. Ideally the user would simply create a file called _posts/xxyyzz.md.wmd, and Jekyll would preprocess it into xxyyzz.md using a plugin I provide, and then process that into HTML in the usual way.
It looks like Jekyll's Converter framework doesn't allow that, because the output_ext function is only given the final extension "wmd", preventing it from returning ".md" for ".md.wmd", ".textile" for ".textile.wmd", etc.
Is there a way to implement a chain of processing steps like this?
EDIT: grammar
Maybe you can try to use a Generator plugin that uses your wmd converter:
require "yourWmdConverter"
module Jekyll
class ConvertWmd < Jekyll::Generator
def initialize(config)
config['convert_wmd'] ||= true
end
def generate(site)
#site = site
site.posts.docs.each { |post| convertWmd post }
end
private
def convertWmd(post)
post.content = yourWmdConverter post.content
end
end
end

Where can I use HAML in Octopress?

So, according to the Octopress official page, it has HAML integration plugin. Naturally, I gave it a try. I backed up my source/_includes/custom/head.html file, converted it to haml and saved it as source/_includes/custom/head.haml. It gave me an error.
I tried doing the same with source/_layouts/page.html file, and it worked like a charm.
My question is, where can I and where can I not use HAML in an Octopress blog?
AS you can see from the source code, the HAML is only processing pages content.
See the convert && output_ext methods.
https://github.com/imathis/octopress/blob/master/plugins/haml.rb
module Jekyll
require 'haml'
class HamlConverter < Converter
safe true
priority :low
def matches(ext)
ext =~ /haml/i
end
def output_ext(ext)
".html"
end
def convert(content)
begin
engine = Haml::Engine.new(content)
engine.render
rescue StandardError => e
puts "!!! HAML Error: " + e.message
end
end
end
end

Two versions of each blog post in Jekyll

I need two versions of each of my posts in a very simple Jekyll setup: The public facing version and a barebones version with branding specifically for embedding.
I have one layout for each type:
post.html
post_embed.html
I could accomplish this just fine by making duplicates of each post file with different layouts in the front matter, but that's obviously a terrible way to do it. There must be a simpler solution, either at the level of the command line or in the front matter?
Update:
This SO question covers creating JSON files for each post. I really just need a generator to loop through each post, alter one value in the YAML front matter (embed_page=True) and feed it back to the same template. So each post is rendered twice, once with embed_page true and one with it false. Still don't have a full grasp of generators.
Here's my Jekyll plugin to accomplish this. It's probably absurdly inefficient, but I've been writing in Ruby for all of two days.
module Jekyll
# override write and destination functions to taking optional argument for pagename
class Post
def destination(dest, pagename)
# The url needs to be unescaped in order to preserve the correct filename
path = File.join(dest, CGI.unescape(self.url))
path = File.join(path, pagename) if template[/\.html$/].nil?
path
end
def write(dest, pagename="index.html")
path = destination(dest, pagename)
puts path
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write(self.output)
end
end
end
# the cleanup function was erasing our work
class Site
def cleanup
end
end
class EmbedPostGenerator < Generator
safe true
priority :low
def generate(site)
site.posts.each do |post|
if post.data["embeddable"]
post.data["is_embed"] = true
post.render(site.layouts, site.site_payload)
post.write(site.dest, "embed.html")
post.data["is_embed"] = false
end
end
end
end
end

Can't get page data from Jekyll plugin

I'm trying to write a custom tag plugin for Jekyll that will output a hierarchical navigation tree of all the pages (not posts) on the site. I'm basically wanting a bunch nested <ul>'s with links (with the page title as the link text) to the pages with the current page noted by a certain CSS class.
I'm very inexperienced with ruby. I'm a PHP guy.
I figured I'd start just by trying to iterate through all the pages and output a one-dimensional list just to make sure I could at least do that. Here's what I have so far:
module Jekyll
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+page.title+'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
And I'm inserting it into my liquid template via {% nav_tree %}.
The problem is that the page variable in the code above doesn't have all the data that you'd expect. page.title is undefined and page.url is just the basename with a forward slash in front of it (e.g. for /a/b/c.html, it's just giving me /c.html).
What am I doing wrong?
Side note: I already tried doing this with pure Liquid markup, and I eventually gave up. I can easily iterate through site.pages just fine with Liquid, but I couldn't figure out a way to appropriately nest the lists.
Try:
module Jekyll
# Add accessor for directory
class Page
attr_reader :dir
end
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+(page.data['title'] || page.url) +'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
page.title is not always defined (example: atom.xml). You have to check if it is defined. Then you can take page.name or not process the entry...
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
unless page.data['title'].nil?
t = page.data['title']
else
t = page.name
end
output += "<li>'+t+'</li>"
end
output += '<ul>'
output
end
Recently I faced a similar problem where the error "cannot convert nill into string" is just blowing my head. My config.yml file holds a line something like this " baseurl: /paradocs/jekyll/out/ " now thats for my local for a server i need to make that beseurl empty and the error starts to appear in build time so finally i have to made " baseurl: / " .. And that's did my job.

Resources