sudo apt-get install python-setuptools
sudo easy_install pip
sudo pip install pelican markdown fabric virtualenv virtualenvwrapper
vi ~/.bashrc (maybe virtualenvwrapper.sh is in other location, change if necessary)
# Virtualenvwrapper
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.shLoad file .bashrc
source ~/.bashrc
Create virtualenv:
mkvirtualenv blog
workon blog
And to leave:
deactivate
pip install --upgrade pelican markdown
Creating a blog on GitHub Pages
We need to make a respository. For example blog, so our blog url will be user.github.com/blog. If you want to set a custom domain see link: Setting up a custom domain with Pages
In parenthesis is the git branch we are working on:
- (
master) Create the post in rst or md (rst and md are abbreviations for resTructuredText and markdown) - (
master) Generate the HTML - (
master) Check the post in a local server - (
master) We could delete the output but dones't matter if we don't because git will ignore with our gitignore file - (
gh-pages) Merge master branch - (
gh-pages) Generate the HTML - (
gh-pages) push all the files (normally all the new HTML) - (
master) push all the files (normally only one post)
git clone [email protected]:user/blog.git
cd ./blog
Create in the root folder a file named .gitignore
vi .gitignore
#Custom
local_settings.py
output
#Python
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
Now we will create a pelican settings file called local_settings.py, this file will not be commited to the git repo, maybe has personal data. But we will upload a blank template named settings.py, so we create also this one, that has the same variables as local_settings.py but without the vars data. Edit the data you need (You can store the local_settings.py data in a private gist manually):
wget -O settings.py https://raw.github.com/getpelican/pelican/master/samples/pelican.conf.py
cp settings.py local_settings.py
mkdir -p ./posts/2013/07
vi welcome-all.md
Title: Welcome All
Slug: welcome-all
Date: 2013-07-22 19:19
Category: Python
Tags: pelican, publishing
Author: Josef Jezek
Summary: Short version for index and feeds
# Welcome All
This is the content of my blog post.To generate the static html we use:
pelican -s ./local_settings.py
This will take all the settings and apply, but if we want to override some settings we could do. For example to specify the ouput we use -o:
pelican -s ./local_settings.py -o /tmp/myBlog
Then we have a new directory named output, our blog is there, so, to test it , insert there and run a simple server:
cd ./output
python -m SimpleHTTPServer 8000
# For Python 3
python -m http.server 8000
Point your browser to localhost:8000 and you will see the blog.
We start the process in the master branch:
git add .
git commit -m "First post: Welcome All"
Push it to master (remember, this doesn't deploy the page, this is our source):
git push origin master
If we havent the gh-pages branch we create:
git branch gh-pages
Change to gh-pages and merge the master branch:
git checkout gh-pages
git merge master
Now generate the HTML. But wait! github doesn't know that our webpage is in output dir, so we need to put our generated HTML in the root of the project, to do that we replace the settings outputdir in the command:
pelican -s ./local_settings.py -o ./
We are ready to deploy, commit all and push:
git add .
git commit -m "Publish Welcome All post"
git push origin gh-pages
We change again to our master branch and we are done :):
git checkout master
Point your browser to you.github.com/blog , Awesome!!!
Fabric is a tool, an awesome tool! to automate things, is most used for remote servers, but also works fine for local automation. Put fabfile.py in the root path of the blog in the master branch.
Now you can use like this:
fab generate: generates the html for developing (while writing)fab serve: Serves the blog in localfab publish: Does all the process of change, commit and publish gh-pages branch, needs to be in master branch while executing the command
The fabfile.py:
import os
import time
from fabric.api import local, lcd, settings
from fabric.utils import puts
#If no local_settings.py then settings.py
try:
from local_settings import OUTPUT_PATH
SETTINGS_FILE = "local_settings.py"
except ImportError:
from settings import OUTPUT_PATH
SETTINGS_FILE = "settings.py"
# Get directories
ABS_ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
ABS_SETTINGS_FILE = os.path.join(ABS_ROOT_DIR, SETTINGS_FILE)
ABS_OUTPUT_PATH = os.path.join(ABS_ROOT_DIR, OUTPUT_PATH)
# Commands
def generate(output=None):
"""Generates the pelican static site"""
if not output:
cmd = "pelican -s {0}".format(ABS_SETTINGS_FILE)
else:
cmd = "pelican -s {0} -o {1}".format(ABS_SETTINGS_FILE, output)
local(cmd)
def destroy(output=None):
"""Destroys the pelican static site"""
if not output:
cmd = "rm -r {0}".format(os.path.join(ABS_ROOT_DIR, OUTPUT_PATH))
else:
cmd = "rm -r {0}".format(output)
with settings(warn_only=True):
result = local(cmd)
if result.failed:
puts("Already deleted")
def serve():
"""Serves the site in the development webserver"""
print(ABS_OUTPUT_PATH)
with lcd(ABS_OUTPUT_PATH):
local("python -m SimpleHTTPServer")
def git_change_branch(branch):
"""Changes from one branch to other in a git repo"""
local("git checkout {0}".format(branch))
def git_merge_branch(branch):
"""Merges a branch in other branch"""
local("git merge {0}".format(branch))
def git_push(remote, branch):
"""Pushes the git changes to git remote repo"""
local("git push {0} {1}".format(remote, branch))
def git_commit_all(msg):
"""Commits all the changes"""
local("git add .")
local("git commit -m \"{0}\"".format(msg))
def publish():
"""Generates and publish the new site in github pages"""
master_branch = "master"
publish_branch = "gh-pages"
remote = "origin"
# Push original changes to master
#push(remote, master_branch)
# Change to gh-pages branch
git_change_branch(publish_branch)
# Merge master into gh-pages
git_merge_branch(master_branch)
# Generate the html
generate(ABS_ROOT_DIR)
# Commit changes
now = time.strftime("%d %b %Y %H:%M:%S", time.localtime())
git_commit_all("Publication {0}".format(now))
# Push to gh-pages branch
git_push(remote, publish_branch)
# go to master
git_change_branch(master_branch)