C2P2 - A simple markdown pages publisher
Code Commit Push Publish
Live and die by documentation.
Matthew Ginnard
Installation
pip install c2p2
or
pip install git+https://github.com/nanvel/c2p2.git
Usage
Fork c2p2_template
The easiest way to start is to fork this template: https://github.com/nanvel/c2p2-template.
Templates API
The application looks for templates inside SOURCE_FOLDER, so we need to add them. Minimal list of files required is:
- site
- engine
- templates
- 404.html
- 500.html
- index.html
- page.html
- label.html
- sitemap.xml
index.html, page.html, label.html and sitemap.xml receives, beside tornado standart template context, variable c, that uses to access a list of pages and labels, for example:
{{ c.page }}
{{ c.page.title }}
{{ c.page.labels }}
{{ c.label }}
{% for page in c.pages %}
{{ c.pages['<page_slug>'] }}
{{ c.pages.for_label('<label_slug>') }}
c.page is available only in page.html. It returns current page object.
- Page object has next attributes:
uri
html
created
modified
title
meta
labels
page.meta returns PageMeta object, where all variables specified in the top of the page is available.
// page.md
created: 2015-10-10T00:00
show_comments: true
labels: Label1
Label2
// page.html
{{ c.page.meta.created }} -> '2015-10-10T00:00'
{{ c.page.meta.created }} -> '2015-10-10T00:00'
{{ c.page.meta.labels }} -> 'Label1'
{{ c.page.meta.get('labels') }} -> 'Label1'
{{ c.page.meta.get_list('labels') }} -> ['Label1', 'Label2']
{{ c.page.meta.show_comments }} -> true
{{ c.page.meta.not_exist }} -> None
page.labels returns list of Label objects connected to the page:
{% for label in c.page.labels %}{{ label.title }}{% end %}
- Label object has next attributes:
title
slug
c.pages returns an iterable that allows to get all pages list. In label.html it return only pages belong to the label. You also can get any page by uri using c.pages.
{% for page in c.pages %}{{ page.title }}{% end %}
{{ c.pages['2010/09/blog-post'].html }}
{{ c.pages.for_label('default') }}
Running the server
To run the application use site/engine/app.py:
import os.path
from c2p2 import app
from c2p2.settings import settings
rel = lambda p: os.path.join(os.path.dirname(os.path.realpath(__file__)), p)
if __name__ == '__main__':
settings.SOURCE_FOLDER = rel('..')
app.run()
Settings
- There are 4 ways to set settings:
default settings (see c2p2/settings.py)
environment variables with C2P2_ prefix: export C2P2_PORT=5000
command line arguments (app.py --PORT=5000)
also you can change them directly settings.PORT = 5000 in site/engine/app.py
- Available settings:
DEBUG: Enable tornado debug mode
PORT: Port the app listening to
SOURCE_FOLDER: Path to folder that contains pages source
UPDATE_TIMEOUT: Number of seconds to rescan source folder. 0 - disable
GITHUB_VALIDATE_IP: Enable GitHub ip validation
GITHUB_SECRET: GitHub web hook secret, optional
GITHUB_BRANCH: GitHub branch to watch
Questions and Answers
Run locally
cd site
virtualenv venv --no-site-packages -p /usr/local/bin/python3.5
source venv/bin/activate
pip install c2p2
python engine/app.py
Open http://localhost:5000 in browser.
Update site if md file was changed without server restart (watch md files)
Use UPDATE_TIMEOUT setting.
Update site on GitHub push
- Create a new GitHub hook for your repository:
url: http://mysite.com/pull
secret: should be equal to GITHUB_SECRET setting value
Production configuration
- Example settings:
DEBUG=false
UPDATE_TIMEOUT=0
GITHUB_VALIDATE_IP=true
GITHUB_SECRET=<webhook secret>
GITHUB_BRANCH=master
Example supervisor configuration:
[program:mysite]
process_name=mysite
directory=/home/deploy/mysite
environment=C2P2_PORT=5100,C2P2_DEBUG=false,C2P2_UPDATE_TIMEOUT=0,C2P2_GITHUB_VALIDATE_ID=true,C2P2_GIHUB_SECRET=123xyz,C2P2_GITHUB_BRANCH=master
command=/home/deploy/mysite/venv/bin/python engine/app.py
user=deploy
stdout_logfile=/var/log/mysite/out.log
stderr_logfile=/var/log/mysite/err.log
autostart=true
autorestart=true
Example nginx configuration:
upstream mysite {
server 127.0.0.1:5100;
}
server {
listen 80;
# If you need to restrict access
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/.htpasswd;
server_name mysite.com;
location / {
proxy_cache off;
proxy_pass http://mysite;
}
location ~* \.(?:css|png|jpe?g|gif|ico|zip|txt)$ {
root /home/deploy/mysite;
log_not_found off;
}
error_page 500 502 503 504 /home/deploy/mysite/engine/templates/500.html;
error_page 400 402 403 404 /home/deploy/mysite/engine/templates/400.html;
}
Favicon and robots.txt
Just add favicon.ico and robots.txt to root folder of your site.
Custom md directives
It is possible to register custom md directives:
from c2p2.utils import ExtensionsRegistry
ExtensionsRegistry.register(extension=MyExtension)
Edit on GitHub link
<a href="https://github.com/nanvel/mysite/blob/master/{{ c.page.uri }}.md" target="_blank">Edit on GitHub</a>
Tests
python -m unittest c2p2.tests
Contribute
If you want to contribute to this project, please perform the following steps:
# Fork this repository
$ virtualenv .env --no-site-packages -p /usr/local/bin/python3.5
$ source .env/bin/activate
$ python setup.py install
$ pip install -r requirements.txt
$ git branch feature_branch master
# Implement your feature and tests
$ git add . && git commit
$ git push -u origin feature_branch
# Send me a pull request for your feature branch
Metadata
Release files for c2p2 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| c2p2-0.1.3.tar.gz | 13.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| c2p2-0.1.3-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 27.8 kB
Release files / c2p2-0.1.3.tar.gz
| Download URL | c2p2-0.1.3.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc00990529528fd85ca45713d14ade259cf83d2819e1e10d3af85a3acd428004
|
|
BLAKE2b-256 checksum How to use checksums |
7a2d1a7c845e171510d0bd85936a9acbd5e3ce32771f428b4bdb99aef61a70c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.10
|
Release files / c2p2-0.1.3-py2.py3-none-any.whl
| Download URL | c2p2-0.1.3-py2.py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
d7501fe115998ae874859ed7c1800ba4d955d1077f23bb3e0406e944eb438bdd
|
|
BLAKE2b-256 checksum How to use checksums |
d91eb6ac401436c10cca313e76d67880de6c466f24c5632b99f123f2afa0b421
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.10
|
Security for c2p2 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.