Customizing Pelican for Static and Dynamic Content

Posted by Mischa Fisher in Technology   
Sun 13 September 2015

This is a a brief summary of a few changes I think were extremely helpful in tweaking the stock Pelican build for a customized, statically generated website:

Rendering Math Markup

Mathjax seemed to be the simplest solution. Embedding the information via a short snippet of code linking to their CDN, and then using simple LaTeX notation within Markdown takes only a minute or two:

<script         src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>

Using Bootstrap for Responsive CSS

Erik Flowers Bootstrap grid introduction is a very nice resource (Click Here)

Customizing Your Own Theme

Web developer Robert Iwancz made a great bare bones framework on which one can build out almost anything. (Click Here for his VoidyNullness Theme)

Using Pelican for a Static Landing Page

Find your .md markdown file that you want to use as your home page content and add the following metadata to the top of the file: (the second change is to prevent your home page from appearing in the menu twice, depending on your theme).

save_as: index.html
status: hidden

Then in a separate .md file that will become your blog content, add the metadata identifier at the top to assign the appropriate HTML template from your templates folder:

Title: (Your Blog Title)
Date: (The Date)
Category: Page
Template: (the title of your blog template, without the .html extension

Finally, copy the content generating loops from the default page templates into your new blog html template:

{% block content_body %}
{% block article %}
{% if articles %}
  {% for article in (articles_page.object_list if articles_page else articles) %}
<article>
  {% for file in CUSTOM_INDEX_ARTICLE_HEADERS %}
    {% include "includes/" + file %}
  {% else %}
    {% include "includes/article_header.html" %}
  {% endfor %}

  {% if ARTICLE_FULL_FIRST is defined and loop.first and not articles_page.has_previous() %}
    <div class="content-body">
    {% if article.standfirst %}
      <p class="standfirst">{{ article.standfirst|e }}</p>
    {% endif %}
    {{ article.content }}
    {% include "includes/comments.html" %}
  </div>
  {% else %}
    {% include "includes/index_summary.html" %}
  {% endif %}
</article>

<hr />
  {% endfor %}
{% endif %}
{% endblock article %}

{% block pagination %}
<nav class="index-pager">
{% if articles_page and articles_paginator.num_pages > 1 %}
    <ul class="pagination">
    {% if articles_page.has_previous() %}
        <li class="prev">
          <a href="{{ SITEURL }}/{{ articles_previous_page.url }}">
        <i class="fa fa-chevron-circle-left fa-fw fa-lg"></i> Previous
      </a>
    </li>
{% else %}
    <li class="prev disabled"><span>
        <i class="fa fa-chevron-circle-left fa-fw fa-lg"></i> 
        Previous</span>
    </li>
{% endif %}

{% for num in articles_paginator.page_range %}
  {% if num == articles_page.number %}
    <li class="active"> <span>{{ num }}</span> </li>
  {% else %}
    <li>
      <a href="{{ SITEURL }}/{{ articles_paginator.page(num).url }}">{{ num }}</a>
    </li>
  {% endif %}
{% endfor %}

{% if articles_page.has_next() %}
    <li class="next">
      <a href="{{ SITEURL }}/{{ articles_next_page.url }}">
        Next <i class="fa fa-chevron-circle-right fa-fw fa-lg"></i>
      </a>
    </li>
{% else %}
    <li class="next disabled">
      <span><i class="fa fa-chevron-circle-right fa-fw fa-lg"></i> Next</span>
    </li>
{% endif %}
</ul>
{% endif %}

Hiding Pages from the Menu

Quite simple, just change the metadata on any given page's .md file to:

Status: Hidden

Embedding Data from a CSV

To generate my reading list, I use a piece of javascript that references the base .csv containing all the books. The script is fantastic because it allows all the flexibility of using a .csv to store the data, without needing a server side scripting language (which a static site on Amazon S3 doesn't have the luxury of relying on).

<div class="d3-chart"></div>

<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="d3.min.js?v=3.2.8"></script>

<script type="text/javascript"charset="utf-8">
    d3.text("/images/data.csv", function(data) {
    var parsedCSV = d3.csv.parseRows(data);

    var container = d3.select(".d3-chart")
    .append("table")

    .selectAll("tr")
    .data(parsedCSV).enter()
    .append("tr")

    .selectAll("td")
    .data(function(d) { return d; }).enter()
    .append("td")
    .text(function(d) { return d; });
    });
</script>

Server and PHP free Contact Forms

FormSpree is ridiculously headache free and works very well (Click Here).

Adding a CSS Parallax Effect

Using Javascript is an option since the browser does the work, rather than a server; however, I found a pure CSS approach to be cleaner and easier. Keith Clark's demo HERE is superb.


 
    
 
 

Comments