Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jekyll - Map multiple URLs to same Jekyll file

Tags:

jekyll

I have a custom page for Jekyll: I have a news.markdown file like the following:

{% assign posts_per_page = 5 %}
{% for post in site.categories.ro offset:pagination_skip limit:posts_per_page %}
    ...
    {{ post.content }}
    ...
{% endfor %}
{% include nav.html %}

Where nav.html is in the _includes directory and it looks like this:

{% if pagination_skip %}
  {% capture pagination_skip %}
    {{pagination_skip | plus: posts_per_page}}
  {% endcapture %}
{% else %}
  {% assign pagination_skip = posts_per_page %}
{% endif %}

<div class="next">
  <a rel="prev" href="{{site.basepath}}ro/news/{{ pagination_skip }}">Next</a>
</div>

What I want is for the url .../ro/news/5 to be mapped to the content of news.markdown such that pagination_skip there is 5. Same for 10, 15, whatever. Moreover, .../ro/news/0 should be the same as .../ro/news/ if possible.

Can I do that? How?

I'd like to use as few extensions as possible.

like image 386
Mihai Maruseac Avatar asked Apr 02 '12 18:04

Mihai Maruseac


1 Answers

You try to do it wrong. You want to have a dynamic handling of a URL parameter. Jekyll is a static web generator. So you need to generate all the page that will be visited. You can a generator for that. Please have a look at Generator section on page https://github.com/mojombo/jekyll/wiki/Plugins

I worked on a generator for what you want to do and it works pretty nicely, I also created the 'prev' and 'next' button. Please have a look and try it. It works for all categories (not only the ro one), but you can customize it if you want.

folder structure

 | -- _plugins
    ` news.rb
 | -- _layouts
    ` news.html
 | -- _includes
    ` nav.html
 | -- _config.yml
 | -- ro
    ` -- _posts
      | -- 2012-04-10-test.textile
      | -- 2012-04-10-test2.textile
      | -- 2012-04-10-test4.textile
      | -- 2012-04-10-test6.textile
      | -- 2012-04-10-test15.textile
      | -- 2012-04-10-test3.textile
      ` -- 2012-04-10-test5.textile
  ` _site

the genrator news.rbruby code

module Jekyll

  class NewsPage < Page
    def initialize(site, base, dir, category, posts_number, posts_per_page, pagination_skip)
      @site = site
      @base = base
      @dir = dir
      @name = "news_#{pagination_skip}.html"

      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'news.html')
      self.data['category'] = category
      self.data['posts_per_page'] = posts_per_page
      self.data['pagination_skip'] = pagination_skip
      if pagination_skip != 0
        self.data['prev_pagination_skip'] = pagination_skip - posts_per_page
      end
      if pagination_skip + posts_per_page < posts_number
        self.data['next_pagination_skip'] = pagination_skip + posts_per_page
      end
    end
  end

  class NewsGenerator < Generator
  safe true
    def generate(site)
      if site.layouts.key? 'news'
        dir = site.config['category_dir'] || 'categories'
        site.categories.keys.each do |category|
          posts_number = site.categories[category].length
          pagination_skip = 0;
          posts_per_page = 5;
          begin
            write_news_page(site, File.join(dir, category), category, posts_number, posts_per_page, pagination_skip)
            pagination_skip += posts_per_page;
          end while pagination_skip < posts_number
        end
      end
    end

    def write_news_page(site, dir, category, posts_number, posts_per_page, pagination_skip)
      index = NewsPage.new(site, site.source, dir, category, posts_number, posts_per_page, pagination_skip)
      index.render(site.layouts, site.site_payload)
      index.write(site.dest)
      site.pages << index
    end
  end
end

The layout of the news.html file

---
---

{% for post in site.categories[page.category] offset:page.pagination_skip limit:page.posts_per_page %}
  {{ post.content }}
{% endfor %}
{% include nav.html %}

The include navigation nav.html

<div class="nav">
  {% if page.prev_pagination_skip %}
    <a rel="prev" href="{{site.basepath}}categories/{{page.category}}/news_{{page.prev_pagination_skip}}.html">Prev</a>
  {% endif %}
  {% if page.next_pagination_skip %}
    <a rel="next" href="{{site.basepath}}categories/{{page.category}}/news_{{page.next_pagination_skip}}.html">Prev</a>
  {% endif %}
</div>

Give it a try and let me let me know if you like it.

like image 77
Baptiste Pernet Avatar answered Oct 27 '22 12:10

Baptiste Pernet