A static site generator for python developers
The idea behind this project is that everything is a plugin, so, that is really easy for developers do anything that runs away from a blog site, using Python.
You create a .py file where you specify your build process, basically, the paths, datas, and what plugins to use.
Pypeflow is very simple:
- Read all files in source_path creating a big dict with all files
- Call the plugins, which manipulates the dict in any way they need
- Write all files in build_path
Use pip:
pip install pypeflow
Install the plugins needed for your build, see a list of disponible plugins bellow
pypeflow = Pypeflow(
source_path=os.path.join(BASE_DIR, 'content'),
build_path=os.path.join(BASE_DIR, 'output'),
templates_path=os.path.join(BASE_DIR, 'templates'),
collections={ # Collections are for group files by pattern, so you can pass same data for multiple files
'recipes': {
'pattern': r'^/recipes/',
'permalink': '/recipes/:category/:title/', # used by permalinks plugin
'sort': 'date',
'reverse': True,
},
},
plugins=(
FrontmatterPlugin(filter_pattern=r'\.md$'), # extract frontmatter data from file
MarkdownPlugin(), # convert markdown to html
PaginatePlugin( # create pagination pages (/recipes/, /recipes/2/, ...)
filter_collections=['recipes'],
per_page=10,
template='recipes.html',
permalink_first='/recipes/',
permalink='/recipes/:page/',
sort='date',
sort_reverse=True,
),
PermalinksPlugin(filter_collections=['recipes']), # generate url for pages
ExcerptsPlugin(size=160), # generates excerpts from file contents
FeedPlugin(filter_collections=['recipes']), # creates a RSS xml file
Jinja2Plugin(), # render template
)
)
pypeflow.build() # write files on build_path
pypeflow.serve() # starts a dev server using build_path as root
Follow the link of the plugin for details on dependencies and instructions to use them.
- Excerpts Create excerpts property from text
- Feed Create RSS feed
- Frontmatter Read frontmatter data and update files
- Jinja2 Template engine used to render html files
- Less Compile less to css
- Markdown Compile markdown to html
- Paginate Creates pagination pages
- Permalinks Creates url property
- Thumbnail Creates thumbnails for images
It is very easy to do a plugin, just make a python class with a run(self, pypeflow, files) method
class ByPypeflowPlugin(object):
def run(self, pypeflow, files):
for path, file in files.items():
if path.endswith('.html'):
new_contents = '{} <p>By pypeflow</p>'.format(file['contents'].read().decode('utf-8))
file['contents'] = io.BytesIO(new_contents)
For convenience, there is Base plugins classes:
- pypeflow.plugins.BasePlugin - Base class, implements filter by pattern or collection
- pypeflow.plugins.BaseThreadPlugin - Used for threaded processing files
- pypeflow.plugins.BaseAsyncPlugin - Used when there is need for high I/O operations
The above example using the BasePlugin:
class ByPypeflowPlugin(object):
def process_file(self, path, file):
new_contents = '{} <p>By pypeflow</p>'.format(file['contents'].read().decode('utf-8))
file['contents'] = io.BytesIO(new_contents)
# using the plugin like this
ByPypeflowPlugin(filter_pattern=r'.html$')