Skip to content

How to Integrate Pelican Plugins

Paul edited this page Aug 23, 2016 · 1 revision

Introduction to Pelican Plugins: Readers vs. Generators

Most Pelican plugins come in two different flavors, Readers and Generators.

A Reader defines how to read new formats of input data. In the pyvideo project, we define a custom JSONReader which is capable of processing the JSON files in pyvideo-data, and populating the python representations of a Page or Article needed by Pelican to be able to generate the HTML page.

A Generator takes the python representations of Pages and Articles that have been created by the various Readers, and generates the HTML files which will be served.

More information about Reader and Generator classes can be found in the pelican plugin documentation.

What that means for pyvideo

Because we are reading from the pyvideo-data JSON files directly, we cannot change those files to add additional data that might be needed by a Pelican plugin. To expose such additional metadata, we will have to change the json_reader.py modules itself. The process of doing this is outlined in the below example.

Example: pelican-alias plugin

To see some of the things we need to be aware of when integrating new Pelican plugins, let us use the pelican-alias plugin as an example.

To use this plugin, it required the addition of a new metdata attribute named alias. The documentation for this plugin describes what changes you need to make if you were to using restructured text or Markdown files.

Restructured Text

My Aliased Post
##############################################
:date: 2013-05-31 22:09
:category: Pelican
:slug: my-aliased-post
:alias: /2013/05/my-aliased-post/, /2013/even-older-post-address

My content goes here.

Markdown

Title: Another Aliased Post
Date: 2013-06-01 21:10
Category: Pelican
Alias: /2013/06/another-aliased-post/
       /2013/even-older-aliased-post-address

My content goes here.

However, because we are using a custom JSONReader, we will have to insert the alias attribute into the Page/Article metadata another way.

To understand how to do this, we will need to look at the source of the json_reader.py module in the plugins directory of the project. In particular, our changes will be to the read() function.

def read(self, filename):
        with open(filename, 'r') as f:
            json_data = json.loads(f.read())

        metadata = {'title': _get_and_check_none(json_data, 'title', 'Title'),
                    'category': _get_and_check_none(json_data, 'category', 'Default'),
                    'tags': _get_and_check_none(json_data, 'tags', []),
                    'date': _get_and_check_none(json_data, 'recorded', '1990-01-01'),
                    'slug': _get_and_check_none(json_data, 'slug', 'Slug'),
                    'authors': _get_and_check_none(json_data, 'speakers', []),
                    'videos': _get_and_check_none(json_data, 'videos', []),
                    'media_url': _get_media_url(json_data),
                    'thumbnail_url': _get_and_check_none(json_data, 'thumbnail_url', ''),
                    'language': _get_and_check_none(json_data, 'language', ''),
        }

        ...
        content = '<h1>Summary</h1>'
        ...

        return content, metadata

This function will be called on every JSON file present in the pyvideo-data/data folder, and returns two items: The HTML content which will be directly displayed for that article (in this case, the variable content), and a dictionary of metadata (the variable metadata)

The pelican-alias plugin is asking us to create a new metadata attribute name alias. Since we aren't manually creating restructured text or Markdown files, and we don't want to add unnecessary data to the pyvideo-data JSON files, we will need to add an entry with the key alias to the metadata dict in the function above.

Let's say that we wanted to create an alias for our articles so that they could be accessed via a url of the structure '{category}/1/{title}'. That would look something like the following.

def read(self, filename):
        with open(filename, 'r') as f:
            json_data = json.loads(f.read())
		
        
        metadata = {'title': _get_and_check_none(json_data, 'title', 'Title'),
                    'category': _get_and_check_none(json_data, 'category',
                    ...
        }

		# CHANGES HERE. You add the new alias item to the metadata dict
        # and it will show up as expected.
        alias = '{}/1/{}'.format(metadata['category'], metadata['title'])
        metadata['alias'] = alias
        
        ...
        content = '<h1>Summary</h1>'
        ...

        return content, metadata