-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhow-to-setup-github-blog-via-pelican.html
executable file
·315 lines (284 loc) · 14.6 KB
/
how-to-setup-github-blog-via-pelican.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<!DOCTYPE html>
<html lang="en">
<head>
<title>How to setup Github Blog via Pelican</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Carson's Tech Hut Full Atom Feed" />
<link href="/feeds/tutorial.atom.xml" type="application/atom+xml" rel="alternate" title="Carson's Tech Hut Categories Atom Feed" />
<script>
/* Javascript code to toggle between adding and removing the
"responsive" class to nav when the user clicks on the icon */
function myFunction() {
var x = document.getElementById("nav-bar");
if (x.className === "nav") {
x.className += " responsive";
} else {
x.className = "nav";
}
}
</script>
</head>
<body>
<div class="navigation pure-menu pure-menu-horizontal">
<div class="nav", id="nav-bar">
<a href="/" class="page-container pure-menu-heading pure-menu-link nav">Carson's Tech Hut</a>
<ul class="pure-menu-list">
<li class="pure-menu-item"><a href="../archives.html" class="pure-menu-link">All posts</a></li>
<li class="pure-menu-item"><a href="../categories.html" class="pure-menu-link">Categories</a></li>
<li class="pure-menu-item"><a href="../tags.html" class="pure-menu-link">Tags</a></li>
</ul>
<a href="javascript:void(0);" class="icon pure-menu-link" onclick="myFunction()">
<i class="fas fa-bars"></i>
</a>
</div>
</div>
<div class="page-container">
<div class="entry-content">
<div class="post-meta pure-u">
<div class="pure-u">
<img src="../theme/images/authors/Logo.png" class="post-avatar" alt="Go to the profile of Carson Zhang">
</div>
<div class="pure-u meta-data">
<a href="/author/carson-zhang.html" class="category">Carson Zhang</a><br />
Senior Software Developer
<br />
<abbr title="2020-04-12T00:00:00-06:00">Sun 12 April 2020</abbr>
• 11 min read
</div>
</div>
</div>
<div class="article-header-container">
<div class="background-image-container">
<div class="background-image-small">
<div class="title-container">
<h1>How to setup Github Blog via Pelican</h1>
</div>
</div>
</div>
</div>
<div class="entry-content">
<!--
<div align="right">
Author:<br>
<a href="/author/carson-zhang.html">Carson Zhang</a><br>
</div>
-->
<p>There are many ways to setup a Github blog, but since I love Python I think it makes sense to use Pelican, which is a Static Site Generator, Powered by Python. </p>
<h2>Set up environment</h2>
<ol>
<li>Create a blog directory for all blog content and styles: <code>mkdir <blogname></code></li>
<li>Go into the blog directory: <code>cd <blogname></code></li>
<li>Create a file called <code>.gitignore</code>, and add in the content from <a href="https://github.com/github/gitignore/blob/master/Python.gitignore">this file</a>. The <code>.gitignore</code> file is used to omitted certain dynamic compiled file when commit your changes.</li>
<li>Install and activate a virtual environment. You could use Anaconda, pipenv, or virtualenv. You can see my tutorials for <a href="https://zmcddn.github.io/the-ultimate-guide-to-setup-multiple-python-environment-with-anaconda-and-sublime-text.html">Anaconda</a>, <a href="https://zmcddn.github.io/pipenv-tutorial-the-official-package-control-for-pyton.html">pipenv</a>, or <a href="https://zmcddn.github.io/setup-virtualenv-for-any-project.html">virtualenv</a>.</li>
<li>
<p>Create a file called <code>requirements.txt</code> in the blog directory with the following content: </p>
<div class="highlight"><pre><span></span>Markdown==3.2.1
pelican==3.7.1
jupyter>=1.0
ipython>=4.0
nbconvert>=4.0
beautifulsoup4
ghp-import==0.4.1
matplotlib==1.5.1
</pre></div>
</li>
<li>
<p>Make sure your virtual environment is activated and run <code>pip install -r requirements.txt</code> in the blog directory to install all of the required packages. </p>
</li>
</ol>
<h2>Create blog</h2>
<ul>
<li>Run <code>pelican-quickstart</code> in the blog directory and follow the interactive setup sequence.</li>
<li>Feel free to hit the <code>Enter</code> key to accept the default values except for the following lines:<ul>
<li>the title of the website</li>
<li>the author of the website</li>
<li>n for the URL prefix</li>
<li>timezone</li>
</ul>
</li>
</ul>
<h2>Install Jupyter plugin for Pelican</h2>
<p>There are a lot of plugins that are super handy for Pelican, and jupyter plugin is definitely one among them. Follow the steps below to install the plugin:</p>
<ol>
<li>Run <code>git init</code> in the blog folder</li>
<li><code>mkdir plugins</code></li>
<li><code>git submodule add git://github.com/danielfrg/pelican-ipynb.git plugins/ipynb</code></li>
<li>
<p>Open <code>pelicanconf.py</code> and add the following lines:</p>
<div class="highlight"><pre><span></span>MARKUP = ('md', 'ipynb')
PLUGIN_PATHS = ['./plugins']
PLUGINS = ['ipynb.markup']
IGNORE_FILES = ['.ipynb_checkpoints']
</pre></div>
<ul>
<li>The first 3 lines of code tell Pelican to activate the plugin when generating HTML and the last line fixes a common error 'Could not find metadata...'</li>
</ul>
</li>
</ol>
<p>There is also a github repo that has all the available plugins for Pelican and you can find it <a href="https://github.com/getpelican/pelican-plugins">here</a></p>
<h2>Create posts from Jupyter Notebook</h2>
<ol>
<li>Write anything (code or markdown cells) in a jupyter notebook</li>
<li>Copy the file into the <strong>content directory</strong> in the blog directory</li>
<li>Create a <strong>txt file</strong> with the same name of your notebook file and an <code>.ipynb-meta</code> extension. <ul>
<li>For example: <code>first-post.ipynb-meta</code></li>
</ul>
</li>
<li>Its content should be formatted as follows:<div class="highlight"><pre><span></span><span class="n">Title</span><span class="o">:</span> <span class="n">First</span> <span class="n">Post</span>
<span class="n">Slug</span><span class="o">:</span> <span class="n">first</span><span class="o">-</span><span class="n">post</span>
<span class="n">Date</span><span class="o">:</span> <span class="mi">2020</span><span class="o">-</span><span class="mi">04</span><span class="o">-</span><span class="mi">12</span> <span class="mi">12</span><span class="o">:</span><span class="mi">12</span>
<span class="n">Category</span><span class="o">:</span> <span class="n">posts</span>
<span class="n">Tags</span><span class="o">:</span> <span class="n">python</span><span class="o">,</span> <span class="n">tutorial</span><span class="o">,</span> <span class="n">pelican</span>
<span class="n">Author</span><span class="o">:</span> <span class="n">Carson</span> <span class="n">Z</span><span class="o">.</span>
<span class="n">Summary</span><span class="o">:</span> <span class="n">This</span> <span class="k">is</span> <span class="n">my</span> <span class="n">first</span> <span class="n">post</span><span class="o">!</span>
</pre></div>
</li>
</ol>
<h2>Create a GitHub Page</h2>
<ol>
<li>Log in/Sign up for GitHub</li>
<li>Create a repo in your account and name it <code><username>.github.io</code>. <ul>
<li>Substitute <code><username></code> with your GitHub username.</li>
<li>For example, mine is <code>zmcddn</code> </li>
<li>Refer to this <a href="https://help.github.com/en/github/getting-started-with-github/create-a-repo">official guide</a> for repo creation</li>
</ul>
</li>
<li><code>cd</code> to the blog directory and run <code>git remote add origin git@github.com:<username>/<username>.github.io.git</code></li>
<li>Set <code>SITEURL</code> in <code>publishconf.py</code> to <code>http://<username>.github.io</code><ul>
<li>For example, mine is <code>https://zmcddn.github.io</code> (remember to remove the trailing slash if there is one)</li>
</ul>
</li>
</ol>
<h2>Pick a theme</h2>
<ol>
<li>Choose a theme <a href="http://www.pelicanthemes.com/">here</a></li>
<li>Go to the blog root folder (i.e. <code><blogname></code> folder) and create a theme folder through <code>mkdir theme</code></li>
<li><code>cd theme</code> and <code>git clone --recursive https://github.com/getpelican/pelican-themes pelican-themes</code></li>
<li>Open the <code>pelicanconf.py</code> and add this line: <code>THEME = '<path_to_chosen_theme>'</code><ul>
<li>For example, <code>theme/pelican-themes/tuxlite_tbs</code></li>
</ul>
</li>
</ol>
<p><strong>Note</strong> that once you've chosen your theme, you have to click into the theme page to see how the theme is setup, coz it might need some <em>special configuration</em> and <em>cannot</em> be used directly out of box</p>
<h2>Run the blog locally to see what it looks like</h2>
<ol>
<li>Go to blog output directory: <code>cd <blogname>\output</code></li>
<li>Run <code>python -m pelican.server</code> to spin up the server</li>
<li>Open up you browser (i.e. Chrome) and type in <code>http://localhost:8000/</code>, then you should see you blog</li>
</ol>
<p>If you would like to see theme change or how your new article looks like, each time you've changed anything you could run the following steps to see it locally:</p>
<ol>
<li>Go to blog directory: <code>cd <blogname></code></li>
<li>Run <code>pelican content -s publishconf.py</code> to create html files</li>
<li>Go to the output directory <code>cd output</code></li>
<li>Run <code>python -m pelican.server</code> to spin up the server and you can see it in your browser at <code>http://localhost:8000/</code></li>
</ol>
<h2>Publish posts</h2>
<ol>
<li>Go to blog directory: <code>cd <blogname></code></li>
<li>Create html from notebook files: <code>pelican content</code></li>
<li>Use correct settings for deployment: <code>pelican content -s publishconf.py</code></li>
<li>Import everything in the output folder to the master branch: <code>ghp-import output -b master</code></li>
<li>Push content to GitHub Pages: <code>git push origin master</code></li>
</ol>
<p>In the future, make sure</p>
<ul>
<li>pelican virtual environment is <strong>activated</strong></li>
<li>notebook file containing new post is moved into <strong>content directory</strong></li>
<li>corresponding <strong>ipynb-meta file</strong> has been created</li>
</ul>
<p>and then repeat the 5 steps above to publish new posts.</p>
<h2>A bit more in-depth about the overall setup</h2>
<ul>
<li>This tutorial provides a ste-by-step guide to setup a Github blog via Pelican</li>
<li>The package <code>ghp-import</code> and command <code>ghp-import output -b master</code> is used to push static blog pages to the <code>github.io</code> site so its super easy to setup<ul>
<li>However, if you run <code>git status</code> in your blog directory, you'll see many uncommitted files since <code>ghp-import</code> doesn't work exactly the same as <code>git commit</code> <ul>
<li>Thus you should be very careful with your blog directory and don't use any reset command (I learned it the hard way ...)</li>
<li>A better way is to setup your blog project in another private github repo and use the normal git commit workflow to catch any changes</li>
</ul>
</li>
</ul>
</li>
<li>Pelican uses Jinja templates so all Jinja tags can be used in the templates</li>
<li>How Pelican works is that all your blog articles are stored in the <code>content</code> folder and once you run <code>pelican content</code> it will generate static pages and store them in the <code>output</code> directory, which is used (and pushed) to <code>github.io</code> for display</li>
</ul>
<h2>Summary</h2>
<table>
<thead>
<tr>
<th align="left">Action</th>
<th align="left">Command</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Run local</td>
<td align="left"><code>python -m pelican.server</code> in <strong>output</strong> folder</td>
</tr>
<tr>
<td align="left">create HTML</td>
<td align="left"><code>pelican content</code></td>
</tr>
<tr>
<td align="left">Setup deployment</td>
<td align="left"><code>pelican content -s publishconf.py</code></td>
</tr>
<tr>
<td align="left">Setup import for github</td>
<td align="left"><code>ghp-import output -b master</code></td>
</tr>
<tr>
<td align="left">Push to github</td>
<td align="left"><code>git push origin master</code></td>
</tr>
</tbody>
</table>
<h2>Reference</h2>
<ul>
<li><a href="https://shaynemei.github.io/hackore/how_to_pelican.html#Pick-a-theme">How to Publish a Pelican Blog via GitHub</a></li>
<li><a href="https://www.dataquest.io/blog/how-to-setup-a-data-science-blog/">Building a Data Science Blog for Your Portfolio</a></li>
</ul>
</div>
<footer>
<div class="tags">
<a href="/tag/python.html">Python</a>
<a href="/tag/pelican.html">Pelican</a>
<a href="/tag/blog.html">Blog</a>
<a href="/tag/github.html">Github</a>
</div>
<div class="pure-g post-footer">
<div class="pure-g">
<div class="pure-g poster-info">
<div class="pure-u">
<a href="/author/carson-zhang.html"><img src="../theme/images/authors/Logo.png" alt=""></a>
</div>
<div class="pure-u">
<h3 class="author-name"><a href="/author/carson-zhang.html">Carson Zhang</a></h3>
<p class="author-description">
I'm a senior software developer, passionated with artificial intellgence and
web development.
</p>
</div>
</div>
</div>
<!--
-->
</div>
</footer>
</div>
<footer class="index-footer">
<div class="footer-wide">
<p><a href="">Carson's Tech Hut</a>© Carson Zhang 2020</p>
</div>
<div class="footer-narrow">
<p><a href="">Carson's Tech Hut</a><br>
© Carson Zhang 2020</p>
</div>
</footer>
<link rel="stylesheet" href="../theme/css/pure-min.css" />
<link rel="stylesheet" href="../theme/css/grids-responsive-min.css" />
<link rel="stylesheet" href="../theme/fontawesome-free-5.13.0-web/css/all.min.css" />
<link rel="stylesheet" href="/theme/css/main.css" />
</body>
</html>