<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>mtik00</title>
    <link>https://mtik00.com/</link>
    <description>Recent content on mtik00</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 09 Nov 2017 14:52:30 -0700</lastBuildDate>
    <atom:link href="https://mtik00.com/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Jinja2 Cache Busting URLs in Python</title>
      <link>https://mtik00.com/2017/11/jinja2-cache-busting-urls/</link>
      <pubDate>Thu, 09 Nov 2017 14:52:30 -0700</pubDate>
      
      <guid>https://mtik00.com/2017/11/jinja2-cache-busting-urls/</guid>
      <description>

&lt;p&gt;Cache busting is a technique the gives web developers a compromise between
asset load speeds and new features.  In this article,
we&amp;rsquo;ll discuss a &lt;em&gt;pure Python&lt;/em&gt; way of implementing this feature in your Jinja2
templates.&lt;/p&gt;

&lt;h1 id=&#34;what-is-caching:32848604b4bca00ae54abd221a684de4&#34;&gt;What is &amp;ldquo;caching&amp;rdquo;&lt;/h1&gt;

&lt;p&gt;NOTE: This article will not cover HTML cache headers, proxy settings, etc.&lt;/p&gt;

&lt;p&gt;Everything you see on a web page is &lt;em&gt;loaded&lt;/em&gt; from somewhere.  That &amp;ldquo;somewhere&amp;rdquo;
could be a VPS in the cloud, a &lt;a href=&#34;https://en.wikipedia.org/wiki/Content_delivery_network&#34;&gt;CDN&lt;/a&gt;
service like &lt;a href=&#34;https://www.cloudflare.com/&#34;&gt;CloudFlare&lt;/a&gt;, your machine, and so
on.  We&amp;rsquo;ll call these things &amp;ldquo;assets&amp;rdquo;.  Assets are images and text files used
to tell your browser how the page you are looking at should look.  These are
mostly things that don&amp;rsquo;t really change too often.&lt;/p&gt;

&lt;p&gt;Since assets don&amp;rsquo;t change often, you can &lt;em&gt;really&lt;/em&gt; speed up page loading by using
something called &amp;ldquo;cache&amp;rdquo;.  Serving files from the webserver can be really slow,
especially if it&amp;rsquo;s a very popular website, or your internet connection is slow.
The good news is that if you have visited that page recently, some or all of
the assets will already be on your computer.&lt;/p&gt;

&lt;p&gt;This all happens without much input from you, the user.  Your browser will
cache by default (unless using something like Tor Browser).  Even if you have
your browser cache disabled, the assets may be cached by a service like
&lt;a href=&#34;https://www.cloudflare.com/&#34;&gt;CloudFlare&lt;/a&gt;.  That&amp;rsquo;s out of your control.&lt;/p&gt;

&lt;p&gt;Quick loading is great, but what happens when the version of
&lt;code&gt;cute-puppy.jpg&lt;/code&gt; you have in your cache is different from what&amp;rsquo;s on the server?
You&amp;rsquo;ll continue to see the same old boring puppy image.
&lt;a href=&#34;https://en.wikipedia.org/wiki/Fear_of_missing_out&#34;&gt;FOMO&lt;/a&gt; anyone?&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s also evidence that search engines prioritize websites that use very
long cache times (e.g. Google&amp;rsquo;s own Page Insights tool).  A nice article on
how caching works can be found here: &lt;a href=&#34;https://jakearchibald.com/2016/caching-best-practices/&#34;&gt;https://jakearchibald.com/2016/caching-best-practices/&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&#34;busting-the-cache:32848604b4bca00ae54abd221a684de4&#34;&gt;Busting the cache&lt;/h1&gt;

&lt;p&gt;Web developers use a technique called &amp;ldquo;cache busting&amp;rdquo; to ensure that any
change to &lt;code&gt;cute-puppy.jpg&lt;/code&gt; is immediately seen by users.  They get around any
&amp;ldquo;cache&amp;rdquo; mechanism by generally taking 1 of these approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change the filename: Instead of &lt;code&gt;cute-puppy.jpg&lt;/code&gt;, they&amp;rsquo;ll use something
like &lt;code&gt;cute-puppy-v1.jpg&lt;/code&gt;.  If the change the content, they&amp;rsquo;ll change
the name to &lt;code&gt;cute-puppy-v2.jpg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Change the URL: Instead of using &lt;code&gt;/static/images/cute-puppy.jpg&lt;/code&gt; in
HTML, they&amp;rsquo;ll use something like &lt;code&gt;/static/images/cute-puppy.jpg?v1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea is the same.  Any change a developer makes to the &lt;em&gt;&amp;ldquo;asset&amp;rdquo;&lt;/em&gt; will cause
viewers to download the updated file.&lt;/p&gt;

&lt;p&gt;I prefer the second method.  I think this is cleaner, and causes less overall
churn in my source code control.&lt;/p&gt;

&lt;h1 id=&#34;pre-calculate-vs-jit:32848604b4bca00ae54abd221a684de4&#34;&gt;Pre-calculate vs JIT&lt;/h1&gt;

&lt;p&gt;The way I see it, you have two options here: 1) Use a build step to version your
assets; 2) perform a &amp;ldquo;just in time&amp;rdquo; calculation when the resource is requested.
This really depends on your process, but I don&amp;rsquo;t see a downside to pre-calculating a version.
This method should also perform much better under load.  Admittedly, I&amp;rsquo;m too lazy to measure
it, so &lt;a href=&#34;https://en.wiktionary.org/wiki/YMMV&#34;&gt;YMMV&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I decided to create a script that calculated the &lt;a href=&#34;https://en.wikipedia.org/wiki/Cyclic_redundancy_check&#34;&gt;CRC32&lt;/a&gt;
for each of my static images and store the result in a JSON file.  I load that
file at the start of my script.  This works great!  It does, however, cause a
lookup to occur each time the Jinja2 template is &lt;em&gt;rendered&lt;/em&gt;.  Jinja2 is pretty
good a caching rendered templates (moar cache!), so I think that&amp;rsquo;s fine.&lt;/p&gt;

&lt;p&gt;NOTE: You could also dynamically create this table at application start.  I
chose not to just to keep the start process simple and clean.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s my Python function to calculate the
&lt;a href=&#34;https://en.wikipedia.org/wiki/Cyclic_redundancy_check&#34;&gt;CRC32&lt;/a&gt; for each of my
images:
&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td&gt;&lt;div class=&#34;linenodiv&#34; style=&#34;background-color: #f0f0f0; padding-right: 10px&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color: #0e84b5; font-weight: bold&#34;&gt;zlib&lt;/span&gt;
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color: #06287e&#34;&gt;build&lt;/span&gt;():
    &lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;    Builds the release files&lt;/span&gt;
&lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;# Calculates and stores the CRC32 for all images in &amp;#39;static/images&amp;#39;&lt;/span&gt;
    outfile &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;join(THIS_DIR, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;app&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;cachbuster.json&amp;#39;&lt;/span&gt;)
    image_dir &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; os&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;path&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;join(THIS_DIR, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;html&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;static&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;images&amp;#39;&lt;/span&gt;)
    result &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; {}
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;for&lt;/span&gt; root, dirs, files &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;in&lt;/span&gt; os&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;walk(image_dir):
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;for&lt;/span&gt; fname &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;in&lt;/span&gt; files:
            fpath &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; root &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; fname
            relpath &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; fpath[&lt;span style=&#34;color: #007020&#34;&gt;len&lt;/span&gt;(image_dir) &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;1&lt;/span&gt;:]&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;replace(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #4070a0; font-weight: bold&#34;&gt;\\&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;)
            prev &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;0&lt;/span&gt;
            &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;for&lt;/span&gt; line &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color: #007020&#34;&gt;open&lt;/span&gt;(fpath, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;):
                prev &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; zlib&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;crc32(line, prev)
            result[relpath] &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%x&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;%&lt;/span&gt; (prev &lt;span style=&#34;color: #666666&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;0xFFFFFFFF&lt;/span&gt;)

    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color: #007020&#34;&gt;open&lt;/span&gt;(outfile, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;wb&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;as&lt;/span&gt; fh:
        fh&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;write(json&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;dumps(result, sort_keys&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #007020&#34;&gt;True&lt;/span&gt;, indent&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #40a070&#34;&gt;4&lt;/span&gt;, separators&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;: &amp;#39;&lt;/span&gt;)))
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;

&lt;p&gt;The fancy &lt;code&gt;relpath&lt;/code&gt; thing is so the output is more manageable (more on that
later).  The file output looks a little like this:
&lt;a name=&#34;jsonfile&#34;&gt;&lt;/a&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;{
    &lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;&amp;quot;about-us.jpg&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;8212d43f&amp;quot;&lt;/span&gt;,
    &lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;&amp;quot;favicon.ico&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;be79d92e&amp;quot;&lt;/span&gt;,
    &lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;&amp;quot;slider/title-img-01.jpg&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;5849f6f0&amp;quot;&lt;/span&gt;,
    &lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;&amp;quot;slider/title-img-02.jpg&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;a66c8271&amp;quot;&lt;/span&gt;,
    &lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;&amp;quot;slider/title-img-03.jpg&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;2e2cbe84&amp;quot;&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;h1 id=&#34;jinja2:32848604b4bca00ae54abd221a684de4&#34;&gt;Jinja2&lt;/h1&gt;

&lt;p&gt;&lt;a href=&#34;http://jinja.pocoo.org/&#34;&gt;Jinja2&lt;/a&gt; is a templating tool used by many Python-based
web development frameworks (like &lt;a href=&#34;http://flask.pocoo.org/&#34;&gt;Flask&lt;/a&gt; and
&lt;a href=&#34;https://bottlepy.org&#34;&gt;bottle.py&lt;/a&gt;).  It&amp;rsquo;s really quite handy when it comes to
creating a single HTML file using nice
&lt;a href=&#34;https://en.wikipedia.org/wiki/Object-oriented_programming&#34;&gt;OO&lt;/a&gt;
concepts like inheritance.&lt;/p&gt;

&lt;h2 id=&#34;filter:32848604b4bca00ae54abd221a684de4&#34;&gt;Filter&lt;/h2&gt;

&lt;p&gt;The first thing we want to do is to add a custom Jinja2 &lt;em&gt;filter&lt;/em&gt;.  This is the
thing that will compare some input to our &lt;a href=&#34;#jsonfile&#34;&gt;JSON data&lt;/a&gt; and return a URL.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;CACHEBUSTER &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; json&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;loads(&lt;span style=&#34;color: #007020&#34;&gt;open&lt;/span&gt;(THIS_DIR &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/cachbuster.json&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;read())
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CACHEBUSTER&lt;/code&gt; is just the data that was calculated during our build step.&lt;/p&gt;

&lt;p&gt;&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td&gt;&lt;div class=&#34;linenodiv&#34; style=&#34;background-color: #f0f0f0; padding-right: 10px&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color: #06287e&#34;&gt;imageloader&lt;/span&gt;(partial_path):
    &lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;    Returns the path with a cachbuster tag if found, or the path otherwise.&lt;/span&gt;
&lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;if&lt;/span&gt; partial_path &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;in&lt;/span&gt; CACHEBUSTER:
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/static/images/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; partial_path &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;?&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; CACHEBUSTER[partial_path]

    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/static/images/&amp;#39;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;+&lt;/span&gt; partial_path
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;imageloader&lt;/code&gt; is the thing that we&amp;rsquo;ll use in our Jinja2 templates.
This function accepts a single input, &lt;code&gt;partial_path&lt;/code&gt;.  We check for the
existence of that path in our pre-compiled CRC32 data.  If we find it, we
return a URL with the calculation appended as a &amp;ldquo;query&amp;rdquo;.  If not, we&amp;rsquo;ll assume
that the path is relative to &lt;code&gt;/static/images/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;a href=&#34;#jsonfile&#34;&gt;our data&lt;/a&gt; file from above:
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;print&lt;/span&gt; imageloader(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;slider/title-img-01.jpg&amp;#39;&lt;/span&gt;)
&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/static/images/slider/title-img-01.jpg?5849f6f0&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color: #666666&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;print&lt;/span&gt; imageloader(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;someimage.jpg&amp;#39;&lt;/span&gt;)
&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;/static/images/someimage.jpg&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;All good!  Any time we make a change to &lt;code&gt;slider/title-img-01.jpg&lt;/code&gt;, the
calculation will change, and we&amp;rsquo;ll get a new URL.  Any item that&amp;rsquo;s not
pre-calculated will be returned like normal.&lt;/p&gt;

&lt;p&gt;The last part is to tell Jinja2 about this new filter in &lt;code&gt;app.py&lt;/code&gt;.
&lt;table class=&#34;highlighttable&#34;&gt;&lt;tr&gt;&lt;td&gt;&lt;div class=&#34;linenodiv&#34; style=&#34;background-color: #f0f0f0; padding-right: 10px&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#34;code&#34;&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;jinja2_loader &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; jinja2&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;FileSystemLoader(TEMPLATE_DIR)
jinja2_env &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; jinja2&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;Environment(autoescape&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #007020&#34;&gt;True&lt;/span&gt;, loader&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;jinja2_loader)
jinja2_env&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;filters[&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;imageloader&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; imageloader
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;

&lt;p&gt;The magic is line number &lt;code&gt;3&lt;/code&gt;.  That tells Jinja2 to call our &lt;code&gt;imageloader()&lt;/code&gt;
function any time it sees a filter named &lt;code&gt;imageloader&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&#34;template-use:32848604b4bca00ae54abd221a684de4&#34;&gt;Template Use&lt;/h2&gt;

&lt;p&gt;Here&amp;rsquo;s how I use the new filter inside a template:
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;&lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;img&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;{{&amp;#39;slider/title-img-01.jpg&amp;#39; | imageloader}}&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;alt&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;Title slider image 1&amp;quot;&lt;/span&gt;&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&#39;slider/title-img-01.jpg&#39;&lt;/code&gt; gets passed to our function, which returns
&lt;code&gt;&#39;/static/images/slider/title-img-01.jpg?5849f6f0&#39;&lt;/code&gt;.  That whole string then
goes into the template, resulting in this:
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;&lt;span style=&#34;color: #062873; font-weight: bold&#34;&gt;img&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;/static/images/slider/title-img-01.jpg?5849f6f0&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;alt&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;Title slider image 1&amp;quot;&lt;/span&gt;&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Perfect!  As long as we keep generating our JSON file during our build process,
the templates will always point to the latest asset without regard to our
cache settings.&lt;/p&gt;

&lt;h1 id=&#34;where-to-go-from-here:32848604b4bca00ae54abd221a684de4&#34;&gt;Where to go from here&lt;/h1&gt;

&lt;p&gt;I showed you how I cache-bust the images from one of my websites.  This is done
in pure Python, without other tools like &lt;code&gt;Grunt&lt;/code&gt;.  If you are already using
compile tools, you may as well find out how they do cache-busting.  But what
fun is that?&lt;/p&gt;

&lt;p&gt;This can be extended to your other assets.  For example, why not to your
&lt;code&gt;.css&lt;/code&gt; and &lt;code&gt;.js&lt;/code&gt; too?  That excersize is left up to the reader ;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Windows, Git, and SSH Keys</title>
      <link>https://mtik00.com/2017/11/windows-git-and-ssh-keys/</link>
      <pubDate>Tue, 07 Nov 2017 16:14:47 -0700</pubDate>
      
      <guid>https://mtik00.com/2017/11/windows-git-and-ssh-keys/</guid>
      <description>

&lt;p&gt;&lt;code&gt;Git&lt;/code&gt; has the ability to use SSH keys in order to authenticate communications
with a remote server.  This is a magical thing!  Depending on how you set it
up, you may never have to enter your password again.&lt;/p&gt;

&lt;p&gt;You may find differing opinions, of course.  My suggestion is to store
&lt;em&gt;password-less&lt;/em&gt; keys securely on your development system.  This may seem like
a bad idea, but it&amp;rsquo;s a pretty common thing to do to make your life easier.&lt;/p&gt;

&lt;p&gt;If your laptop/desktop ever gets stolen, it&amp;rsquo;s pretty easy to revoke it&amp;rsquo;s key.&lt;/p&gt;

&lt;h1 id=&#34;generating-keys:cce5ea14931aa06e9fcfd6a79e417c6d&#34;&gt;Generating Keys&lt;/h1&gt;

&lt;p&gt;I do 99% of my development on my Windows computer.  Windows doesn&amp;rsquo;t have any
built-in SSH functionality (we&amp;rsquo;re not talking about &lt;code&gt;WSL&lt;/code&gt; right now).  That
means that you will wind up installing &lt;code&gt;PuTTY&lt;/code&gt;.  It&amp;rsquo;s ok&amp;hellip; everybody&amp;rsquo;s doing
it!&lt;/p&gt;

&lt;p&gt;I like to store my SSH keys in my profile directory.  This will make your life
&lt;em&gt;a lot&lt;/em&gt; easier.  The keys will also be slightly protected with your Windows
login information.  &lt;code&gt;%USERPROFILE%&lt;/code&gt; is also the default place were utilities
will look for your SSH config file.&lt;/p&gt;

&lt;p&gt;In a command Window, type: &lt;code&gt;mkdir %USERPROFILE%\.ssh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generate your first key:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open up &lt;code&gt;PuTTYGen&lt;/code&gt; (might be in your &lt;em&gt;Start menu&lt;/em&gt; if you installed it like that)&lt;/li&gt;
&lt;li&gt;The default settings of &lt;code&gt;2048 RSA&lt;/code&gt; should be ok&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;Generate&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Move your mouse over the window to &lt;em&gt;generate some randomness&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Export these things to your &lt;code&gt;%USERPROFILE%\.ssh&lt;/code&gt; folder (you can ignore the &lt;em&gt;without a passphrase&lt;/em&gt; warnings):

&lt;ul&gt;
&lt;li&gt;Press &lt;strong&gt;Save private key&lt;/strong&gt;: This will save a file with a &lt;code&gt;.ppk&lt;/code&gt; extension.
This is your private key; keep it safe!  This should stay on your dev
machine.&lt;br /&gt;
For this example, name this &lt;code&gt;devmachine.ppk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;From the menu, select &lt;strong&gt;Conversions -&amp;gt; Export OpenSSH Key&lt;/strong&gt;:  This is
your private key exported into something that &lt;code&gt;git&lt;/code&gt; will use.&lt;br /&gt;
For this example, name this &lt;code&gt;devmachine-openssh-private.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Keep the Window open&amp;hellip; the &lt;em&gt;Public key for pasting&lt;/em&gt; is important for
a later step.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here&amp;rsquo;s a screenshot of my screen after I generated the key:&lt;/p&gt;

&lt;p&gt;
&lt;figure &gt;
    
        &lt;img src=&#34;https://mtik00.com/media/puttygen.png&#34; alt=&#34;PuTTY Gen key generated&#34; /&gt;
    
    
&lt;/figure&gt;
&lt;/p&gt;

&lt;h2 id=&#34;userprofile-ssh-config:cce5ea14931aa06e9fcfd6a79e417c6d&#34;&gt;%USERPROFILE%.ssh\config&lt;/h2&gt;

&lt;p&gt;The SSH utilities that &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; use the &lt;code&gt;.ppk&lt;/code&gt; directly will want to use the
&lt;code&gt;devmachine-openssh-private.txt&lt;/code&gt; file that you exported above.  The easiest
way to do this is to create a &lt;code&gt;config&lt;/code&gt; file that tells the utilities which
keys to use for which hosts.&lt;/p&gt;

&lt;p&gt;Run the following command from the command line (careful here, don&amp;rsquo;t delete
the file if it&amp;rsquo;s already there!):
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;type&lt;/span&gt; NUL &amp;gt;&amp;gt; &lt;span style=&#34;color: #bb60d5&#34;&gt;%USERPROFILE%&lt;/span&gt;\.ssh\config
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;This will create an emtpy file.  Now open that file up in your favorite text
editor.  Here&amp;rsquo;s a sample configuration for &lt;code&gt;github.com&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;Host github.com
    StrictHostKeyChecking no
    IdentityFile C:\Users\myusername\.ssh\devmachine-openssh-private.txt
&lt;/pre&gt;&lt;/div&gt;

(replace &lt;code&gt;myusername&lt;/code&gt; with your user name)&lt;/p&gt;

&lt;p&gt;All utilities that support this kind of thing, such as &lt;code&gt;git&lt;/code&gt;, will automatically
use this configuration to log in to the remote system (&lt;code&gt;github.com&lt;/code&gt;, in this
case).&lt;/p&gt;

&lt;p&gt;NOTE: This format of &lt;code&gt;.ssh/config&lt;/code&gt; is the same for both Windows and Linux.&lt;/p&gt;

&lt;h1 id=&#34;github:cce5ea14931aa06e9fcfd6a79e417c6d&#34;&gt;GitHub&lt;/h1&gt;

&lt;p&gt;We&amp;rsquo;re using GitHub in this example, but this holds true for any other remote
host that supports SSH keys (even Linux systems).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go into your &lt;strong&gt;Settings&lt;/strong&gt;, and select &lt;strong&gt;SSH and GPG keys&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;New SSH key&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Give it an appropriate &lt;strong&gt;Title&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Remember the &lt;code&gt;PuTTYGen&lt;/code&gt; window you kept open?  Copy the text in the &lt;strong&gt;Public
key for pasting&amp;hellip;&lt;/strong&gt; section (right click, select &lt;em&gt;Select all&lt;/em&gt;, then right
click and select &lt;em&gt;Copy&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Paste that text into the GitHub page were it says &lt;strong&gt;Key&lt;/strong&gt;.&lt;br /&gt;
NOTE: The thing you copy/paste should start with &lt;code&gt;ssh-rsa&lt;/code&gt; and probably
end with &lt;code&gt;== rsa-key-20171107&lt;/code&gt; (the numbers would change)&lt;/li&gt;
&lt;li&gt;Press the *&lt;em&gt;Add SSH key&lt;/em&gt; button at the bottom of the form.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;rsquo;s it!  Now you can use &lt;code&gt;git clone&lt;/code&gt; to clone your repo using the &lt;strong&gt;Clone
with SSH&lt;/strong&gt; option.  That will also give you the ability to use &lt;code&gt;git pull&lt;/code&gt; and
&lt;code&gt;git push&lt;/code&gt; without entering in your password.&lt;/p&gt;

&lt;h1 id=&#34;bonus-linux-server:cce5ea14931aa06e9fcfd6a79e417c6d&#34;&gt;Bonus: Linux Server&lt;/h1&gt;

&lt;p&gt;Have a Linux server already using SSH?  Great news, you can follow the same
basic steps to allow password-less connections!&lt;/p&gt;

&lt;p&gt;GitHub gave us a nice web interface to add the keys.  No such luck in Linux
(depending on what you think of GUIs).  Still, its a relatively simple process.&lt;/p&gt;

&lt;p&gt;NOTE: These directions really depend on how &lt;code&gt;sshd&lt;/code&gt; is configured; the directions
below are most common.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;mkdir -p ~/.ssh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim ~/.ssh/authorized_keys&lt;/code&gt; (or use a command-line editor your familiar with)&lt;/li&gt;
&lt;li&gt;Add in the same text you pasted into GitHub (&lt;code&gt;ssh-rsa.....== rsa...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Save the file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Change the permissions: &lt;code&gt;chmod -R 600 ~/.ssh&lt;/code&gt; (things may not
work without this)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Back on your Windows machine, make another entry in &lt;code&gt;%USERPROFILE%\.ssh\config&lt;/code&gt;
that points to your Linux server.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Cloudflare with GitHub Pages</title>
      <link>https://mtik00.com/2017/11/cloudflare-with-github-pages/</link>
      <pubDate>Mon, 06 Nov 2017 10:10:08 -0700</pubDate>
      
      <guid>https://mtik00.com/2017/11/cloudflare-with-github-pages/</guid>
      <description>

&lt;p&gt;I recently changed my GitHub pages setup to incorporate the use of CloudFlare,
because, why not?&lt;/p&gt;

&lt;p&gt;NOTE: If you don&amp;rsquo;t have a domain, or don&amp;rsquo;t care about CDN/Caching, the
instructions below are pointless!  Just point people to
&lt;code&gt;https://&amp;lt;username&amp;gt;.github.io&lt;/code&gt;!&lt;/p&gt;

&lt;h1 id=&#34;why:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Why&lt;/h1&gt;

&lt;p&gt;In my &lt;a href=&#34;https://mtik00.com/2015/08/nginx-proxy-for-github-pages/&#34;&gt;
Nginx Proxy for GitHub Pages&lt;/a&gt; post, I explained how
to set up your own web server using Nginx and Let&amp;rsquo;s Encrypt to provide your
own SSL certificate and proxy requests to GitHub.  This is fine, but it still
adds a layer of complexity and requires your own VPS for set up.&lt;/p&gt;

&lt;p&gt;I was recently poking around CloudFlare.  I found out that they have a &lt;em&gt;free&lt;/em&gt;
tier that supports all kinds of neat things.  This includes a &lt;em&gt;shared&lt;/em&gt; SSL
certificate (perfectly fine for GitHub Pages content), CDN, DNS, and of course
caching.  I&amp;rsquo;m always up for a &lt;em&gt;free&lt;/em&gt; introduction to new-to-me technologies.&lt;/p&gt;

&lt;p&gt;Personally, the biggest benefit is that I no longer have to deal with minimizing
anything!  CloudFlare offers the options to minimize things for you (and
bypass that when needed).  This means that my development workflow is quite a
bit easier.  This pretty much negates my
&lt;a href=&#34;https://mtik00.com/2015/08/testing-pipelined-static-content/&#34;&gt;
Testing Pipelined Static Content&lt;/a&gt; post!&lt;/p&gt;

&lt;h1 id=&#34;steps:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Steps&lt;/h1&gt;

&lt;p&gt;Full disclosure: Most of these steps are already online, so you could also
Google them too.&lt;/p&gt;

&lt;h2 id=&#34;cloudflare:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;CloudFlare&lt;/h2&gt;

&lt;p&gt;The first step was to sign up for a CloudFlare account.  That was easy.  During
the setup procress, CloudFlare figured out all of the DNS records I was using
(name servers, mail records, etc).  CloudFlare automatically sets them up as
one would expect.  For example, the &lt;code&gt;MX&lt;/code&gt; records were left alone (which is
exactly what you want).  CloudFlare then tells you what to change on your
registrar.  This makes it so all domain name lookups go through CloudFlare&amp;rsquo;s
DNS.&lt;/p&gt;

&lt;h2 id=&#34;github:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;GitHub&lt;/h2&gt;

&lt;p&gt;The next step was to set up GitHub pages to know about our new domain.  This
is explained
&lt;a href=&#34;https://help.github.com/articles/using-a-custom-domain-with-github-pages/&#34;&gt;
in GitHub&amp;rsquo;s online documentation&lt;/a&gt;.  Just a quick settings change and a new
&lt;code&gt;CNAME&lt;/code&gt; file.  One thing to note: you&amp;rsquo;ll want to add a &lt;code&gt;.nojekyll&lt;/code&gt; file to your
pages folder if you aren&amp;rsquo;t using Jekyll.
&lt;a href=&#34;https://github.com/blog/572-bypassing-jekyll-on-github-pages&#34;&gt;(this is
the best link I found for that)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;wait:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Wait&lt;/h2&gt;

&lt;p&gt;Now you wait!  &lt;code&gt;DNS&lt;/code&gt; changes take a while to propogate through the system.  It
took my work network a full day to pick up the change; my home network only took
a few hours.  You&amp;rsquo;ll know its been changed on your network when you run
&lt;code&gt;nslookup &amp;lt;domain&amp;gt;&lt;/code&gt; and the result points to CloudFlare DNS.&lt;/p&gt;

&lt;h2 id=&#34;back-to-cloudflare:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Back to CloudFlare&lt;/h2&gt;

&lt;p&gt;By now, you should be serving your content through CloudFlare connected to
GitHub.  There are some settings in CloudFlare that you may want to enable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;SSL Full&lt;/code&gt;: On the &lt;strong&gt;Crypto&lt;/strong&gt; page, you can set your &lt;code&gt;SSL&lt;/code&gt; to &lt;code&gt;Full&lt;/code&gt;.  This
will encrypt the connection between CloudFlare and GitHub.  NOTE: You cannot
use &lt;code&gt;Full (strict)&lt;/code&gt; because your hostname is different from GitHub!  You&amp;rsquo;ll
get errors and your site won&amp;rsquo;t work.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Browser Cache Expiration&lt;/code&gt;: On the &lt;strong&gt;Caching&lt;/strong&gt; page, you can now set the
cache expiration.  If you use &lt;em&gt;cache busting&lt;/em&gt; techniques, you can set this
to something in the far future, like &amp;ldquo;6 months&amp;rdquo; or &amp;ldquo;1 year&amp;rdquo;.
&lt;code&gt;Always Online&lt;/code&gt; is an interesting one too.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Auto Minify&lt;/code&gt;: This is a handy feature on the &lt;strong&gt;Speed&lt;/strong&gt; page.  I have
CloudFlare automatically minify my JavaScript, CSS, and HTML.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Always Use HTTPS&lt;/code&gt;: I like always redirecting to HTTPS.  AFter all, this is
one of the reasons I&amp;rsquo;m using CloudFlare.  I&amp;rsquo;ve created a rule on the &lt;strong&gt;Page Rules&lt;/strong&gt;
page to always use https for &lt;code&gt;http://mtik00.com/*&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;NOTE: These changes take affect immediately(-ish).&lt;/p&gt;

&lt;h1 id=&#34;ssl:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;SSL&lt;/h1&gt;

&lt;p&gt;SSL/TLS is the biggest change.  I&amp;rsquo;m no longer encrypting &lt;code&gt;mtik00.com&lt;/code&gt; with
Let&amp;rsquo;s Encrypt.  This is because of 2 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visitors are presented with CloudFlare&amp;rsquo;s SSL certificate&lt;/li&gt;
&lt;li&gt;CloudFlare communicates directly to GitHub using GitHub&amp;rsquo;s SSL certificate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;mtik00.com&lt;/code&gt; is no long providing any SSL.  That should make sense since &lt;code&gt;mtik00.com&lt;/code&gt;
is really a &lt;em&gt;virtual&lt;/em&gt; thing now.  All of the content is served by GitHub and
cached by CloudFlare.&lt;/p&gt;

&lt;h1 id=&#34;posting-process:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Posting Process&lt;/h1&gt;

&lt;p&gt;My process of creating a post is identical to before (thanks to scripting).
The only think I took out from my deployment script was the minification of
things.&lt;/p&gt;

&lt;h1 id=&#34;caveats:99d742c51e999a9338a91c7e4c1114b1&#34;&gt;Caveats&lt;/h1&gt;

&lt;p&gt;Here are some things to consider when choosing this method.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any DNS changes you need (e.g. &lt;code&gt;SPF&lt;/code&gt;, &lt;code&gt;DKIM&lt;/code&gt;, etc) will need to changed
on CloudFlare&amp;rsquo;s &lt;strong&gt;DNS&lt;/strong&gt; settings page.&lt;/li&gt;
&lt;li&gt;Your site will &lt;strong&gt;NOT&lt;/strong&gt; use your certificate (unless you pay CloudFlare to
manage one).  This is not the solution to use a domain-verified certificate.&lt;/li&gt;
&lt;li&gt;This is mainly &lt;em&gt;fire and forget&lt;/em&gt;.  Don&amp;rsquo;t forget how things are set up!&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>virtualenvwrapper-win &#34;No module named pip&#34;</title>
      <link>https://mtik00.com/2015/09/virtualenvwrapper-win-no-module-named-pip/</link>
      <pubDate>Wed, 09 Sep 2015 10:16:16 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/09/virtualenvwrapper-win-no-module-named-pip/</guid>
      <description>&lt;p&gt;If you use virtualenvwrapper on Windows, you may have come across an issue where the environment cannot be created properly due to &amp;ldquo;ImportError: No module named pip&amp;rdquo;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll let you Google the reason; here&amp;rsquo;s a fix.  Basically, you need to create the environment &lt;em&gt;without&lt;/em&gt; &lt;code&gt;setuptools&lt;/code&gt;.  Here are the basic steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;mkvirtualenv --no-setuptools --no-site-packages newenv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wget --no-check-cert https://raw.github.com/pypa/pip/master/contrib/get-pip.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python get-pip.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;del get-pip.py&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because I do this every so often, I&amp;rsquo;ve implemented my own &lt;code&gt;mkvirtualenv&lt;/code&gt; batch file like so:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;@&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;echo&lt;/span&gt; off
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;IF&lt;/span&gt; .&lt;span style=&#34;color: #bb60d5&#34;&gt;%1&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;==&lt;/span&gt; . (
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;echo&lt;/span&gt; Usage: mkvirtualenv &amp;#39;env name&amp;#39;
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;GOTO&lt;/span&gt; :&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;eof&lt;/span&gt;
)

@&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;echo&lt;/span&gt; on
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;call&lt;/span&gt; C:\Python27\Scripts\mkvirtualenv.bat --no-setuptools --no-site-packages &lt;span style=&#34;color: #bb60d5&#34;&gt;%1&lt;/span&gt;
wget --no-check-cert https://raw.github.com/pypa/pip/master/contrib/get-pip.py
python get-pip.py
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;del&lt;/span&gt; get-pip.py
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;FYI: I store batch files like this in &lt;code&gt;C:\bin&lt;/code&gt;.  I then put &lt;code&gt;C:\bin&lt;/code&gt; in my path, so they&amp;rsquo;re available to all of my command-line activities.&lt;/p&gt;

&lt;p&gt;The batch file is not perfect, since the path to the actual &lt;code&gt;mkvirtualenv&lt;/code&gt; is hard coded, but it&amp;rsquo;s &lt;em&gt;far&lt;/em&gt; easier than trying to store the output of something like &lt;code&gt;python -c &amp;quot;import os,sys; print os.path.join(os.path.dirname(sys.executable), &#39;Scripts&#39;, &#39;mkvirtualenv.bat&#39;)&amp;quot;&lt;/code&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Django and Cripsy Form Login with Icons</title>
      <link>https://mtik00.com/2015/08/django-and-cripsy-form-login-with-icons/</link>
      <pubDate>Sun, 30 Aug 2015 21:55:57 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/08/django-and-cripsy-form-login-with-icons/</guid>
      <description>&lt;p&gt;I recently created a website using the very nice &lt;a href=&#34;http://django-edge.readthedocs.org/en/latest/&#34;&gt;Edge&lt;/a&gt; template for a new Django site.  The log in form was nice, but I wanted a form with icons and no labels.  Here&amp;rsquo;s how I did it&amp;hellip;&lt;/p&gt;

&lt;p&gt;The greatest thing is that this was a &lt;em&gt;super easy&lt;/em&gt; change.  I think it looks a lot nicer, to boot.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s what the old login page looked like:

&lt;figure &gt;
    
        &lt;img src=&#34;https://mtik00.com/media/login-before.png&#34; alt=&#34;Default edge login template&#34; /&gt;
    
    
&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;I used the incredible &lt;a href=&#34;http://django-crispy-forms.readthedocs.org/en/d-0/layouts.html?highlight=prependedtext&#34;&gt;&lt;code&gt;PrependedText&lt;/code&gt;&lt;/a&gt; FormHelper item to add a &lt;a href=&#34;http://fortawesome.github.io/Font-Awesome/&#34;&gt;Font Awesome&lt;/a&gt; icon before the field.  I had to set the field labels to empty-strings, as I:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Couldn&amp;rsquo;t figure out the &lt;code&gt;Field&lt;/code&gt; item to set inside &lt;code&gt;PrependedText&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Couldn&amp;rsquo;t use &lt;code&gt;self.helper.form_show_labels = False&lt;/code&gt; because I needed it for the &lt;code&gt;remember_me&lt;/code&gt; field.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here&amp;rsquo;s the python code:
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color: #06287e&#34;&gt;__init__&lt;/span&gt;(&lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;, &lt;span style=&#34;color: #666666&#34;&gt;*&lt;/span&gt;args, &lt;span style=&#34;color: #666666&#34;&gt;**&lt;/span&gt;kwargs):
        &lt;span style=&#34;color: #007020&#34;&gt;super&lt;/span&gt;(LoginForm, &lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;)&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color: #06287e&#34;&gt;__init__&lt;/span&gt;(&lt;span style=&#34;color: #666666&#34;&gt;*&lt;/span&gt;args, &lt;span style=&#34;color: #666666&#34;&gt;**&lt;/span&gt;kwargs)
        &lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;helper &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; FormHelper()
        &lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;fields[&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;]&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;label &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;fields[&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;password&amp;quot;&lt;/span&gt;]&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;label &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span style=&#34;color: #007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;helper&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;layout &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; Layout(
            PrependedText(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;username&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&amp;lt;i class=&amp;quot;fa fa-envelope-o&amp;quot;&amp;gt;&amp;lt;/i&amp;gt;&amp;#39;&lt;/span&gt;, placeholder&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;Enter Email Address&amp;quot;&lt;/span&gt;),
            PrependedText(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;password&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&amp;lt;i class=&amp;quot;fa fa-key&amp;quot;&amp;gt;&amp;lt;/i&amp;gt;&amp;#39;&lt;/span&gt;, placeholder&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;Enter Password&amp;quot;&lt;/span&gt;),
            HTML(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;&amp;lt;a href=&amp;quot;{}&amp;quot;&amp;gt;Forgot Password?&amp;lt;/a&amp;gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;format(
                reverse(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;accounts:password-reset&amp;quot;&lt;/span&gt;))),
            Field(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;remember_me&amp;#39;&lt;/span&gt;),
            Submit(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;sign_in&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;#39;Log in&amp;#39;&lt;/span&gt;,
                   css_class&lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;btn btn-lg btn-primary btn-block&amp;quot;&lt;/span&gt;),
        )
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s the new login form:

&lt;figure &gt;
    
        &lt;img src=&#34;https://mtik00.com/media/login-after.png&#34; alt=&#34;New log in template&#34; /&gt;
    
    
&lt;/figure&gt;
&lt;/p&gt;

&lt;p&gt;The is subtle, but effective!  (I think so, anyways)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Testing Pipelined Static Content</title>
      <link>https://mtik00.com/2015/08/testing-pipelined-static-content/</link>
      <pubDate>Mon, 10 Aug 2015 20:57:46 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/08/testing-pipelined-static-content/</guid>
      <description>&lt;p&gt;After working quite hard on my &lt;code&gt;pre&lt;/code&gt; and &lt;code&gt;post&lt;/code&gt; Hugo pipeline, I needed a way to test the actual content that will be pushed to the server.  Python (once again) to the rescue!&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;really&lt;/em&gt; love Hugo&amp;rsquo;s built-in server.  &lt;code&gt;hugo serve --watch&lt;/code&gt; is truly a great time saver.  However, it has nothing to do with our pipeline (fingerprinting, compressing, etc).  If we want to see what the end result is going to look like, we need a way to serve that content.&lt;/p&gt;

&lt;p&gt;Python has many built-in packages.  That&amp;rsquo;s the main reason it&amp;rsquo;s my language of choice.  Python has a simple web server ready to go.  I use &lt;code&gt;hugo serve --watch&lt;/code&gt; when I&amp;rsquo;m creating my content.  When I want to check the output of my pipeline, I use the following on the command-line:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;cd &lt;span style=&#34;color: #666666&#34;&gt;&amp;lt;&lt;/span&gt;path to content&lt;span style=&#34;color: #666666&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; python &lt;span style=&#34;color: #666666&#34;&gt;-&lt;/span&gt;m SimpleHTTPServer &lt;span style=&#34;color: #40a070&#34;&gt;8000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python -m SimpleHTTPServer 8000&lt;/code&gt; tells Python to load the SimpleHTTPServer module and serve the content it finds in the current working directory on port 8000.  Technically, you are running &lt;code&gt;SimpleHTTPServer.__main__()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The great thing about this is that I can run both the Python server and the Hugo server at the same time, depending on what I need.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s the batch file I use for this:
&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;@&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;echo&lt;/span&gt; off
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color: #bb60d5&#34;&gt;%~dp0&lt;/span&gt;..

&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color: #bb60d5&#34;&gt;%1&lt;/span&gt;|findstr /xr &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;p&amp;quot;&lt;/span&gt; &amp;gt;nul &amp;amp;&amp;amp; (
  &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;goto&lt;/span&gt; :&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;python&lt;/span&gt;
) || (
  &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;goto&lt;/span&gt; :&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;hugo&lt;/span&gt;
)

:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: =============================================================================&lt;/span&gt;
:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: Run python on the already-built static pages.  This is for checking the end&lt;/span&gt;
:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: result of the pipeline to ensure everything worked.&lt;/span&gt;
:&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;python&lt;/span&gt;
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;pushd&lt;/span&gt; mtik00.github.io
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;start&lt;/span&gt; python -m SimpleHTTPServer 8000
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;popd&lt;/span&gt;
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;goto&lt;/span&gt; :&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;end&lt;/span&gt;
:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: =============================================================================&lt;/span&gt;

:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: =============================================================================&lt;/span&gt;
:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: Clean the Hugo build directory, then call Hugo to serve the content&lt;/span&gt;
:&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;hugo&lt;/span&gt;
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;IF&lt;/span&gt; &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;EXIST&lt;/span&gt; build (
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;rmdir&lt;/span&gt; /q /s build
    sleep 1
)

&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;start&lt;/span&gt; hugo server --watch --source=&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;site&amp;quot;&lt;/span&gt; --bind=&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;
&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;goto&lt;/span&gt; :&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;end&lt;/span&gt;
:&lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;: =============================================================================&lt;/span&gt;

:&lt;span style=&#34;color: #002070; font-weight: bold&#34;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Create a Post Date/Time with Python</title>
      <link>https://mtik00.com/2015/08/create-a-post-date-time-with-python/</link>
      <pubDate>Sun, 09 Aug 2015 21:07:30 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/08/create-a-post-date-time-with-python/</guid>
      <description>&lt;p&gt;I like to create draft posts as kind of &lt;em&gt;markers&lt;/em&gt; for things I want to write about in the future.  Unfortunately, when I do a &lt;code&gt;hugo new post...&lt;/code&gt;, the current date is already put in the front matter for me. That&amp;rsquo;s &lt;strong&gt;really&lt;/strong&gt; handy if I&amp;rsquo;m posting right away, but not so much if I have a &lt;em&gt;draft&lt;/em&gt; for a really long time.&lt;/p&gt;

&lt;p&gt;If you have Python installed on your system, here&amp;rsquo;s a quick one-liner to print out the current &lt;a href=&#34;https://docs.python.org/2/library/time.html?highlight=time.strftime#time.strftime&#34;&gt;date/time&lt;/a&gt; in Hugo&amp;rsquo;s (really Go&amp;rsquo;s) format:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;python &lt;span style=&#34;color: #666666&#34;&gt;-&lt;/span&gt;c &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;import time; print time.strftime(&amp;#39;%Y-%m-&lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;T%H:%M:%S&amp;#39;, time.localtime()) + &amp;#39;&lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%+03i&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;:00&amp;#39; % (-1*(time.altzone / 3600) if time.daylight else (-1*(time.timezone/3600)));&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;I have that line wrapped in a batch file that I can run called &lt;code&gt;htime.bat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s quick and easy!  It&amp;rsquo;s &lt;em&gt;slightly&lt;/em&gt; easier than just changing it with your text editor.&lt;/p&gt;

&lt;p&gt;NOTE: This command only takes into consideration timezones that change on the hour!  Sorry &lt;a href=&#34;http://www.timeanddate.com/worldclock/india/new-delhi&#34;&gt;India&lt;/a&gt; (and more)&amp;hellip;&lt;/p&gt;

&lt;p&gt;UPDATE 8/10/2015: I just came across the &lt;a href=&#34;https://gohugo.io/commands/hugo_undraft/&#34;&gt;&lt;code&gt;hugo undraft&lt;/code&gt;&lt;/a&gt; command that does basically the same thing.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nginx Proxy for GitHub Pages</title>
      <link>https://mtik00.com/2015/08/nginx-proxy-for-github-pages/</link>
      <pubDate>Sun, 02 Aug 2015 22:15:32 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/08/nginx-proxy-for-github-pages/</guid>
      <description>

&lt;p&gt;&lt;a href=&#34;https://www.nginx.com/&#34;&gt;Nginx&lt;/a&gt; is my favorite web server.  I find it &lt;em&gt;much&lt;/em&gt; easier to configure and use than Apache.  If you believe the hype, it&amp;rsquo;s also faster and consumes fewer resources.  That&amp;rsquo;s really not the point of this article, however.&lt;/p&gt;

&lt;p&gt;This point of this article is to show you how you configure Nginx on your server to serve static content that is actually served by GitHub pages.&lt;/p&gt;

&lt;h1 id=&#34;tl-dr:fae300191a56abce8a320c4057f8da61&#34;&gt;TL;DR&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;pages&lt;/code&gt; repo&lt;/li&gt;
&lt;li&gt;Clone it to your local computer&lt;/li&gt;
&lt;li&gt;Check in your static files&lt;/li&gt;
&lt;li&gt;Set up your Nginx configuration file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -am&amp;quot;...&amp;quot; &amp;amp;&amp;amp; git push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Profit!&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&#34;github-pages:fae300191a56abce8a320c4057f8da61&#34;&gt;GitHub Pages&lt;/h1&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com&#34;&gt;GitHub&lt;/a&gt; alows users to store static web content (HTML, CSS, and JS) in specific repositories.  The only real caveat is that you must have &lt;code&gt;index.html&lt;/code&gt; in your repository root.  Of course, your files will also be public if you are using the free service.  This service is called &lt;a href=&#34;https://pages.github.com/&#34;&gt;GitHub Pages&lt;/a&gt;.  &lt;a href=&#34;https://github.com/mtik00/mtik00.github.io&#34;&gt;Here is this blogs repository&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&#34;content:fae300191a56abce8a320c4057f8da61&#34;&gt;Content&lt;/h1&gt;

&lt;p&gt;There are lots of ways to create your site.  I use &lt;a href=&#34;http://gohugo.io&#34;&gt;Hugo&lt;/a&gt; to generate the blog out of easy-to-generate Markdown files.  Nice and &lt;em&gt;relatively&lt;/em&gt; simple.  However you do it, you&amp;rsquo;ll need to be able to generate static content.&lt;/p&gt;

&lt;h1 id=&#34;nginx:fae300191a56abce8a320c4057f8da61&#34;&gt;Nginx&lt;/h1&gt;

&lt;p&gt;GitHub will serve up your pages to the web world just fine.  For this blog, you can go to &lt;a href=&#34;https://mtik00.github.io&#34;&gt;https://mtik00.github.io&lt;/a&gt; to browse it.  It looks the same as &lt;a href=&#34;https://mtik00.com&#34;&gt;https://mtik00.com&lt;/a&gt;, with the exception of the SSL key.  If you want users to go to your custom URL, and you want to manage your own SSL keys, you&amp;rsquo;ll need to set up an Nginx &lt;em&gt;proxy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;NOTE: If you don&amp;rsquo;t care about SSL and only want a custom domain, read this instead: &lt;a href=&#34;https://help.github.com/articles/setting-up-a-custom-domain-with-github-pages/&#34;&gt;https://help.github.com/articles/setting-up-a-custom-domain-with-github-pages/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since your content is hosted on GitHub, you only need an Nginx configuration file that redirects.  Here&amp;rsquo;s the configuration that I use (without the SSL setup):&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;server&lt;/span&gt; {
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;server_name&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;mtik00.com&lt;/span&gt;;
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;listen&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;443&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;ssl&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;spdy&lt;/span&gt;;

    &lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;# The site is actually hosted on github pages.  Using this proxy location&lt;/span&gt;
    &lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;# allows us to secure the connection with our own SSL keys, instead of the&lt;/span&gt;
    &lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;# generic github.io SSL keys.&lt;/span&gt;

    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;location&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;/&lt;/span&gt; {
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;proxy_pass&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;https://mtik00.github.io&lt;/span&gt;;
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;proxy_intercept_errors&lt;/span&gt; &lt;span style=&#34;color: #60add5&#34;&gt;on&lt;/span&gt;;

        &lt;span style=&#34;color: #60a0b0; font-style: italic&#34;&gt;# allow GitHub to pass caching headers instead of using our own&lt;/span&gt;
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;expires&lt;/span&gt; &lt;span style=&#34;color: #60add5&#34;&gt;off&lt;/span&gt;;
    }
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;magic&lt;/em&gt; happens when a user navigates to &lt;a href=&#34;https://mtik00.com/&#34;&gt;https://mtik00.com/&lt;/a&gt;.  When the happens, the &lt;code&gt;location /&lt;/code&gt; block matches, and all of the content is silently served from &lt;a href=&#34;http://mtik00.github.io&#34;&gt;http://mtik00.github.io&lt;/a&gt;.  How cool is that?&lt;/p&gt;

&lt;p&gt;Users will never know (nor will they care).&lt;/p&gt;

&lt;h1 id=&#34;why:fae300191a56abce8a320c4057f8da61&#34;&gt;Why&lt;/h1&gt;

&lt;p&gt;This might all seem a bit silly.  Really, if already have a web server running Nginx, why set up the proxy in the first place?  Why not just store your content on the server?  Well, the way I see it, this method has the following benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git commit -am&amp;quot;...&amp;quot; &amp;amp;&amp;amp; git push&lt;/code&gt; is all that&amp;rsquo;s needed to update your site&lt;/li&gt;
&lt;li&gt;Your content won&amp;rsquo;t take up any space on your web server&lt;/li&gt;
&lt;li&gt;You get to control your content entirely&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Only you can decide if it&amp;rsquo;s work it.  It is for me.  I can decide at any time to move the content off of GitHub, I can create new SSL keys as needed, and all I need to do to update is to &lt;code&gt;push&lt;/code&gt; the new pages back up to GitHub.&lt;/p&gt;

&lt;h1 id=&#34;folder-structure:fae300191a56abce8a320c4057f8da61&#34;&gt;Folder Structure&lt;/h1&gt;

&lt;p&gt;As I&amp;rsquo;ve mentioned before, I use Hugo to generate the static HTML files that are served by GitHub.  That, in itself, is a separate repository.  I started off with everything in the same repo.  It was a little odd, but it &lt;em&gt;wasn&amp;rsquo;t quite right&lt;/em&gt;.  My development files were in a folder called &lt;code&gt;dev&lt;/code&gt;, and the generated HTML files were in the repo root.  I decided to make things a little more complex to make the static html file repo cleaner.&lt;/p&gt;

&lt;p&gt;I currently have two projects:  1) My development files; 2) My GitHub pages static HTML files.  The trick here is that my GitHub pages repo is a &lt;em&gt;subtree&lt;/em&gt; located inside my other repo.  It looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mtik00-pages/
mtik00-pages/mtik00.github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The base folder contains my development enviroment (batch files, python scripts, hugo binaries, etc).  The only thing &lt;code&gt;mtik00-pages/mtik00.github.com&lt;/code&gt; contains are HTML/CSS/JS files.  My normal process goes like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;hugo new content/post&lt;/li&gt;
&lt;li&gt;edit the post in &lt;a href=&#34;http://www.sublimetext.com/&#34;&gt;SublimeText2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;commit the new content: &lt;code&gt;git add . &amp;amp;&amp;amp; git commit -am&amp;quot;adding new post&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;build the static pages:  &lt;code&gt;hugo -d&amp;quot;mtik00.github.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;deploy the static pages: &lt;code&gt;cd mtik00.github.com &amp;amp;&amp;amp; git add -A . &amp;amp;&amp;amp; git commit -am&amp;quot;new pages&amp;quot; &amp;amp;&amp;amp; git push&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Wordpress XML to Hugo MD</title>
      <link>https://mtik00.com/2015/07/wordpress-xml-to-hugo-md/</link>
      <pubDate>Thu, 30 Jul 2015 15:39:23 -0600</pubDate>
      
      <guid>https://mtik00.com/2015/07/wordpress-xml-to-hugo-md/</guid>
      <description>

&lt;p&gt;I&amp;rsquo;ve had a personal family blog in one form of another since 2002.  For the last 10 years, give or take, I used &lt;a href=&#34;https://wordpress.com/&#34;&gt;WordPress&lt;/a&gt;.  It&amp;rsquo;s a very fine and handy tool; especially for non-technical types.  That&amp;rsquo;s the real issue&amp;hellip; I&amp;rsquo;m a &lt;em&gt;technical type&lt;/em&gt;.  I started looking for something simpler, easier to maintain, and more secure.  That led me to &lt;em&gt;static site generators&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I won&amp;rsquo;t go into the details, but there &lt;a href=&#34;http://lmgtfy.com/?q=static+site+generators&#34;&gt;are a few to choose from&lt;/a&gt;.  I settled on &lt;a href=&#34;http://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;.  I was mainly interested in it because it seemed easy, was written in &lt;a href=&#34;http://golang.org/&#34;&gt;Go&lt;/a&gt;, and yes, it had a pretty website.&lt;/p&gt;

&lt;h1 id=&#34;the-conversion:689bb1f7ccd933f475db2ace11b77cea&#34;&gt;The Conversion&lt;/h1&gt;

&lt;p&gt;One of the many nice things about WordPress is the ability to export your site into XML (side note, I &lt;em&gt;loath&lt;/em&gt; XML).  There are some examples and script that do the conversion for you, but what fun would that be?  In the process, I learned that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Most HTML is Markdown compliant (that is, Markdown &amp;ldquo;understands&amp;rdquo; it)&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s hard to tell an HTML-to-MD converter exactly how you want the HTML parsed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On to the script!  &lt;a href=&#34;https://gist.github.com/mtik00/75c8f555b49365395e32&#34;&gt;You can view the script here.&lt;/a&gt;.  I won&amp;rsquo;t go over it in gory detail, but here are the basics.&lt;/p&gt;

&lt;p&gt;WP exports everything, but I was only concerned with the post &lt;code&gt;body&lt;/code&gt;, the date it was published (&lt;code&gt;pubDate&lt;/code&gt;), the &lt;code&gt;category&lt;/code&gt;&amp;rsquo;s (I called them &lt;code&gt;tags&lt;/code&gt; in the script), the &lt;code&gt;title&lt;/code&gt;, and where it should go.  The last part took some predetermined knowledge of how I wanted my Hugo site to be set up (read &lt;a href=&#34;http://gohugo.io/extras/permalinks/&#34;&gt;&lt;code&gt;[permalinks]&lt;/code&gt;&lt;/a&gt;).  If you look at the exported XML file, there are &lt;em&gt;lots&lt;/em&gt; of metadata that I&amp;rsquo;m ignoring (YMMV).&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;    tree &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; ET&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;parse(xml_path)
    channel &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; tree&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;find(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;channel&amp;quot;&lt;/span&gt;)
    wp_version_check(channel)

    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;for&lt;/span&gt; post &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;in&lt;/span&gt; channel&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;findall(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;item&amp;quot;&lt;/span&gt;):
        &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;print&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;post title:&amp;quot;&lt;/span&gt;, post&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;find(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;)&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;text
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;WP puts all of the posts in a &amp;lt;channel&amp;gt; element.  Each post is located inside an &amp;lt;item&amp;gt; element.  So far, so good!  Now all we need to do is to loop through each item and grab the data we need.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34; style=&#34;background: #f0f0f0&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color: #06287e&#34;&gt;wp_to_hugo_date&lt;/span&gt;(wp_date):
    &lt;span style=&#34;color: #4070a0; font-style: italic&#34;&gt;&amp;quot;&amp;quot;&amp;quot;Converts a UTC time string from the WordPress XML to a Hugo time string.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    date &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;strptime(wp_date, &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;%a, &lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt; %b %Y %H:%M:%S +0000&amp;quot;&lt;/span&gt;)
    date &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; calendar&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;timegm(date)
    ltime &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;localtime(date)
    date &lt;span style=&#34;color: #666666&#34;&gt;=&lt;/span&gt; time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;strftime(&lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;T%H:%M:%S&amp;quot;&lt;/span&gt;, ltime)

    date &lt;span style=&#34;color: #666666&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color: #4070a0&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #70a0d0; font-style: italic&#34;&gt;%+03i&lt;/span&gt;&lt;span style=&#34;color: #4070a0&#34;&gt;:00&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;%&lt;/span&gt; (&lt;span style=&#34;color: #666666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color: #40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;*&lt;/span&gt; (time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;altzone &lt;span style=&#34;color: #666666&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;3600&lt;/span&gt;) &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;if&lt;/span&gt; time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;daylight &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;else&lt;/span&gt; (&lt;span style=&#34;color: #666666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color: #40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color: #666666&#34;&gt;*&lt;/span&gt; (time&lt;span style=&#34;color: #666666&#34;&gt;.&lt;/span&gt;timezone &lt;span style=&#34;color: #666666&#34;&gt;/&lt;/span&gt; &lt;span style=&#34;color: #40a070&#34;&gt;3600&lt;/span&gt;)))
    &lt;span style=&#34;color: #007020; font-weight: bold&#34;&gt;return&lt;/span&gt; ltime, date
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m using this function to convert the &lt;code&gt;pubDate&lt;/code&gt; from WordPress to the format that Hugo uses.  Nothing real special here, although I&amp;rsquo;m sure there&amp;rsquo;s a much better way to calculate the time zone.  The string-formatted &lt;code&gt;pubDate&lt;/code&gt; will go into the posts front matter, and I parse &lt;code&gt;ltime&lt;/code&gt; to figure out where the post should go.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s the basics.  I ran this script on my entire WordPress XML dump (only 90+ pages, nothing too big).  It created all of the Markdown posts full of HTML.  It was up to me to then go in and adjust some of the HTML so it was rendered a little better by Hugo.  Most of my time spent was on downloading images, checking them into Git, and reworking the gallery posts to use my new template (which is awesome, because now I can use &lt;code&gt;{{ gallery path/to/gallery/folder }}&lt;/code&gt; in my markdown).&lt;/p&gt;

&lt;p&gt;The point is, however, I was able to have a fully functioning port of my WordPress blog to Hugo in a matter of hours (the script only took a second to run).  Woot!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Archive Place Holder</title>
      <link>https://mtik00.com/archives/empty/</link>
      <pubDate>Sat, 01 Jan 1972 00:00:02 -0600</pubDate>
      
      <guid>https://mtik00.com/archives/empty/</guid>
      <description></description>
    </item>
    
    <item>
      <title>About Me</title>
      <link>https://mtik00.com/about/</link>
      <pubDate>Sat, 01 Jan 1972 00:00:01 -0600</pubDate>
      
      <guid>https://mtik00.com/about/</guid>
      <description>

&lt;p&gt;I&amp;rsquo;ve been writing software since I figured out how to hack &lt;a href=&#34;https://en.wikipedia.org/wiki/Lemonade_Stand&#34;&gt;Lemonade Stand&lt;/a&gt; back in the late 1970&amp;rsquo;s (ok, &lt;em&gt;writing&lt;/em&gt; is a bit of a stretch).  I absolutely &lt;strong&gt;adored&lt;/strong&gt; my &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_64&#34;&gt;Commodore 64&lt;/a&gt;.  Man, those power bricks just didn&amp;rsquo;t last!&lt;/p&gt;

&lt;p&gt;My interest in computers never waned.  I moved on from my C64, to my parents &lt;a href=&#34;https://en.wikipedia.org/wiki/Commodore_128&#34;&gt;C128&lt;/a&gt; (dual disk drives!  woot!), to a 286, 386, 486, Pentium, and so on.  After a short stint in the &lt;a href=&#34;http://www.goarmy.com/&#34;&gt;military&lt;/a&gt;, I moved to Colorado Springs to go to school.&lt;/p&gt;

&lt;p&gt;I graduated from &lt;a href=&#34;http://www.uccs.edu/&#34;&gt;UCCS&lt;/a&gt; in the spring of 1999 with a Bachelors of Electrical Engineering.  I really thought I wanted to be an analog designer.  That dream was short lived!  I soon realized that what truly made me happy was programming.  With that knowledge in hand, I went back to school.&lt;/p&gt;

&lt;p&gt;I graduated from &lt;a href=&#34;http://www.coloradotech.edu/&#34;&gt;CTU&lt;/a&gt; in the spring of 2005 with a Masters of Science in Software Engineering.  I finally had the piece of paper that &lt;em&gt;proved&lt;/em&gt; I could write code.  I left my semiconductor job for a much-more-software-focused job in electrical test equipment (logic analyzers, to be exact).  That worked out great, until they laid me off (no worries, I enjoyed the 3 months severance).&lt;/p&gt;

&lt;p&gt;Luckily, I was hired right away.  I continue to work in the storage industry, but I&amp;rsquo;m happy to say I&amp;rsquo;m 100% software focused!  I&amp;rsquo;ve been writing code to facilitate test automation since 2007 (mainly &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt;).  I really enjoy the challenge and I love the instant feedback I get since my customers sit right next to me.&lt;/p&gt;

&lt;h1 id=&#34;about-the-name:6083a88ee3411b0d17ce02d738f69d47&#34;&gt;About The Name&lt;/h1&gt;

&lt;p&gt;The name &lt;code&gt;mtik&lt;/code&gt;, pronouced &amp;ldquo;&lt;em&gt;em tick&lt;/em&gt;&amp;rdquo;, was my very first &lt;a href=&#34;https://en.wikipedia.org/wiki/EverQuest&#34;&gt;EverQuest&lt;/a&gt; character (a Gnome &lt;a href=&#34;https://en.wikipedia.org/wiki/EverQuest#Casters&#34;&gt;Necromancer&lt;/a&gt;).  I had played quite a bit of &lt;a href=&#34;https://en.wikipedia.org/wiki/Ultima_Online&#34;&gt;Ultima Online&lt;/a&gt; prior to the release of EverQuest, but I can&amp;rsquo;t remember any of my character names.  I used &lt;code&gt;mtik&lt;/code&gt; as a character name for all of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Massively_multiplayer_online_role-playing_game&#34;&gt;MMORPGs&lt;/a&gt; that followed.  It stuck!  I became quite fond of it.  I added the &lt;code&gt;00&lt;/code&gt; to the end due to a name-collision when I signed up for something or another.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>