<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Static Sites on Techformist</title>
    <link>https://techformist.com/categories/static-sites/</link>
    <description>Recent content in Static Sites on Techformist</description>
    <image>
      <url>https://techformist.com/logo.svg</url>
      <link>https://techformist.com/logo.svg</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 08 Jan 2020 15:30:00 +0000</lastBuildDate><atom:link href="https://techformist.com/categories/static-sites/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Automatic Dynamic Sidebars in Vuepress</title>
      <link>https://techformist.com/automatic-dynamic-sidebar-vuepress/</link>
      <pubDate>Wed, 08 Jan 2020 15:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/automatic-dynamic-sidebar-vuepress/</guid>
      <description>&lt;p&gt;How can you get automatic sidebars to be generated in Vuepress depending on the page?&lt;/p&gt;
&lt;h2 id=&#34;the-situation&#34;&gt;The Situation&lt;/h2&gt;
&lt;p&gt;Vuepress is simple.&lt;/p&gt;
&lt;p&gt;Being simple is rather difficult. In the case of Vuepress, the difficulty can show up in unexpected places.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://techformist.com/using-vuepress/&#34;&gt;Starting with Vuepress is simple enough&lt;/a&gt;. Equally simple is enabling navigation on your site at multiple levels through a &amp;ldquo;sidebar&amp;rdquo; and/or a &amp;ldquo;navbar&amp;rdquo;. Specifically for the sidebar - you can enable in by adding a couple of lines in &lt;code&gt;/docs/.vuepress/config.js&lt;/code&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>How can you get automatic sidebars to be generated in Vuepress depending on the page?</p>
<h2 id="the-situation">The Situation</h2>
<p>Vuepress is simple.</p>
<p>Being simple is rather difficult. In the case of Vuepress, the difficulty can show up in unexpected places.</p>
<p><a href="/using-vuepress/">Starting with Vuepress is simple enough</a>. Equally simple is enabling navigation on your site at multiple levels through a &ldquo;sidebar&rdquo; and/or a &ldquo;navbar&rdquo;. Specifically for the sidebar - you can enable in by adding a couple of lines in <code>/docs/.vuepress/config.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">//...
</span></span></span><span class="line"><span class="cl">  <span class="nx">themeConfig</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">sidebar</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Home&#34;</span><span class="p">,</span> <span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">]</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Misc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;more&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="c1">//...
</span></span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>The above change will create a sidebar for your site with links under <code>Home</code> and <code>Misc</code>. The title of links will be either -</p>
<ul>
<li>the title of the page (or)</li>
<li>the first header element within the markdown files that the links point to</li>
</ul>
<p>This is how it looks -</p>
<p><img loading="lazy" src="/misc/vuepress-site-navbar-sidebar.gif" type="" alt="vuepress-site-navbar-sidebar"  /></p>
<p>As you can see: the <code>H2</code> headers will be links grouped below the file links.</p>
<p>But, what if you need to do more -</p>
<ol>
<li>you want to create different sidebars for different pages. For e.g. if you are creating a site that has a bunch of different guides instead of one guide with multiple chapters. When you go to specific pages (which are represented as folders in Vuepress root folder), the navigation links have to change to point to different markdown files in a specific folder</li>
<li>you may want to continue having <code>H2</code> behaviour be Vuepress default - show the links within the specific markdown files</li>
<li>you <em>don&rsquo;t want</em> to write links to all the files by hand. Instead you want the system to automatically &ldquo;see&rdquo; the content to be linked</li>
</ol>
<p>In a recent project I needed the &ldquo;Admin&rdquo;, &ldquo;Developer&rdquo; and other folders to have their own sidebars with navigation links. -</p>
<p><img loading="lazy" src="/misc/vuepress-dynamic-sidebar-appearance.jpg" type="" alt="vuepress-dynamic-sidebar-appearance"  /></p>
<p>This sidebar is slightly different from Vuepress default, which seemingly assumes that all of the content is one big happy family. Vuepress by default enables links just point to the different markdown files in the document root, and to the <code>H2</code> elements when the parent links are expanded.</p>
<h2 id="solutions">Solutions</h2>
<p>Let&rsquo;s look at how we can customise sidebar in Vuepress.</p>
<p>Vuepress is after all powered by Vue - so customisation is not really a complex problem. However, I did not find this as straight forward as something like <a href="https://gridsome.org/">Gridsome</a>. In Gridsome you just create a component for navigation like any sane developer and the system will exactly do what it has to - render the navbar.</p>
<p>Vuepress&rsquo;s navbar is driven by config (and if applicable, plugins) - so this seemed not so elegant(!?) at first. But as always - all you need to solve world&rsquo;s problems are good docs and some time.</p>
<p>Given below are three solutions that I tried to different degrees of success. The solution that worked for me is at the end because I am heartless and believe in making people scroll.</p>
<h3 id="solution-1-use-vuepress-plugin-auto-sidebar-plugin">Solution 1. Use <code>vuepress-plugin-auto-sidebar</code> plugin</h3>
<p>The plugin <a href="https://github.com/shanyuhai123/vuepress-plugin-auto-sidebar">vuepress-plugin-auto-sidebar</a> seemed to do exactly what I wanted.</p>
<p>To install a plugin in Vuepress, all you have to do is -</p>
<ol>
<li>Install the package using npm/yarn</li>
<li>Use the plugin in config</li>
</ol>
<p>Let&rsquo;s get this going. Go to Vuepress folder and install package.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm install --save vuepress-plugin-auto-sidebar
</span></span></code></pre></div><p>Include plugin in <code>/docs/.vuepress/config.js</code>-</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl">  <span class="nx">plugins</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s2">&#34;vuepress-plugin-auto-sidebar&#34;</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">titleMap</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;salesforce-for-students&#34;</span><span class="o">:</span> <span class="s2">&#34;Salesforce for Students&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;pd1-guide&#34;</span><span class="o">:</span> <span class="s2">&#34;Platform Developer I Certification Guide&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;admin-guide&#34;</span><span class="o">:</span> <span class="s2">&#34;Admin Certification Guide&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;why-learn-salesforce&#34;</span><span class="o">:</span> <span class="s2">&#34;Why Learn Salesforce?&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">misc</span><span class="o">:</span> <span class="s2">&#34;Miscellany&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This configuration will provide custom titles for the different folders and automatically pick up the files within the folder to create distinct, dynamic navigation bars.</p>
<p>In the ideal world, this should have been it and I should not have been sitting around to create a blog post about all the circus. But hey - ideal world is not exciting.</p>
<ol>
<li>Getting started was bit of a bother. The documentation of the package is in Chinese and there are not many examples. <a href="https://translate.googleusercontent.com/translate_c?depth=1&amp;hl=en&amp;prev=search&amp;rurl=translate.google.com&amp;sl=zh-CN&amp;sp=nmt4&amp;u=https://github.com/shanyuhai123/vuepress-plugin-auto-sidebar&amp;usg=ALkJrhjEoGnpFTMIIBtnn7mQe2ZOOMElQw">Google translation helped to an extent</a></li>
<li>I could not quite figure out how <code>autoNext</code> and <code>autoPrev</code> worked. My files were not exactly sorted in the folder and sort order of the links in the sidebar was messed up</li>
<li>There were random failures. You could never say when sidebars generation failed (silently), and for the life of me, I could not figure out why. With dozens of files in different folders, I was quite frustrated with all the cut/pasting of content just to see what caused the program to fail</li>
<li>If you have a sub-folder with a <code>README</code> in the root, the README does not show in the navigation. This is expected as per Vuepress, but I could never say when the README appeared as a separate link and when it wouldn&rsquo;t</li>
</ol>
<h3 id="solution-2-use-vuepress-bar">Solution 2: Use <code>vuepress-bar</code></h3>
<p><a href="https://www.npmjs.com/package/vuepress-bar">vuepress-bar</a> was another ready solution that seemed promising.</p>
<p>First, install the package.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">npm i --save vuepress-bar
</span></span></code></pre></div><p>Next, include the plugin in <code>/docs/.vuepress/config.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">getConfig</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;vuepress-bar&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">themeConfig</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span><span class="nx">getConfig</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">__dirName</span><span class="si">}</span><span class="sb">/..`</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>That&rsquo;s it - you should have the new sidebars working. This worked more reliably than solution (1), but I could not figure out how to generate distinct sidebars for indidvidual content folders. All links appeared under one title - which was not ideal for my case.</p>
<p><img loading="lazy" src="/misc/vuepress-bar-sidebar.jpg" type="" alt="vuepress-bar-sidebar"  /></p>
<p>Consider using this library if you just want a dynamic sidebar (and/or a navbar).</p>
<h3 id="solution-3-go-custom">Solution 3: Go custom</h3>
<p>My final solution was just doing everything myself. This was not as scary as it initially appeared - all it took was a couple of lines of code.</p>
<p>Get started by doing changes in <code>/docs/.vuepress/config.js</code> -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;fs&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;path&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">//...
</span></span></span><span class="line"><span class="cl">  <span class="nx">themeConfig</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">sidebar</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;/why-learn-salesforce/&#34;</span><span class="o">:</span> <span class="nx">getSideBar</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;why-learn-salesforce&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Why Salesforce?&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;/admin-guide/&#34;</span><span class="o">:</span> <span class="nx">getSideBar</span><span class="p">(</span><span class="s2">&#34;admin-guide&#34;</span><span class="p">,</span> <span class="s2">&#34;Admin Certification Guide&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;/pd1-guide/&#34;</span><span class="o">:</span> <span class="nx">getSideBar</span><span class="p">(</span><span class="s2">&#34;pd1-guide&#34;</span><span class="p">,</span> <span class="s2">&#34;PD1 Certification Guide&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;/salesforce-for-students/&#34;</span><span class="o">:</span> <span class="nx">getSideBar</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;salesforce-for-students&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Salesforce for Students&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="c1">//...
</span></span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getSideBar</span><span class="p">(</span><span class="nx">folder</span><span class="p">,</span> <span class="nx">title</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">extension</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;.md&#34;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">files</span> <span class="o">=</span> <span class="nx">fs</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">readdirSync</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">__dirname</span><span class="si">}</span><span class="sb">/../</span><span class="si">${</span><span class="nx">folder</span><span class="si">}</span><span class="sb">`</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">filter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">=&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nx">item</span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">()</span> <span class="o">!=</span> <span class="s2">&#34;readme.md&#34;</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">        <span class="nx">fs</span><span class="p">.</span><span class="nx">statSync</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">__dirname</span><span class="si">}</span><span class="sb">/../</span><span class="si">${</span><span class="nx">folder</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span> <span class="nx">item</span><span class="p">)).</span><span class="nx">isFile</span><span class="p">()</span> <span class="o">&amp;&amp;</span>
</span></span><span class="line"><span class="cl">        <span class="nx">extension</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">item</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">[{</span> <span class="nx">title</span><span class="o">:</span> <span class="nx">title</span><span class="p">,</span> <span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="p">...</span><span class="nx">files</span><span class="p">]</span> <span class="p">}];</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>And voila, you have the brand new sidebar -</p>
<p><img loading="lazy" src="/misc/vuepress-sidebar-auto-generate-function.jpg" type="" alt="vuepress-sidebar-auto-generate-function"  /></p>
<p>You can see that -</p>
<ol>
<li>There&rsquo;s a distinct sidebar for each folder - first level links are the files within the folder</li>
<li>Links to <code>README</code> and other files are consistent</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>Using Vuepress and other stories</title>
      <link>https://techformist.com/using-vuepress/</link>
      <pubDate>Wed, 04 Dec 2019 18:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/using-vuepress/</guid>
      <description>&lt;p&gt;I am a big fan of Vue and cannot breathe without static sites. So, it is only natural that I play around and implement Vue-based static sites for fun and profit.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a distilled-down version of my experience with &lt;a href=&#34;https://vuepress.vuejs.org/&#34;&gt;Vuepress&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;the-situation&#34;&gt;The Situation&lt;/h2&gt;
&lt;p&gt;I create static sites that are &amp;ldquo;real&amp;rdquo; websites. Typically the following factors in a static site generator help -&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A cool, easy-to-customise home page&lt;/li&gt;
&lt;li&gt;Themes/starter projects that make life easy&lt;/li&gt;
&lt;li&gt;Plugins that can extend functionality of core software&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Although I had played around Vuepress quite a bit, I always ended up choosing non-Vue technologies like Hugo, or Vue-based static site generators like Gridsome or Saber.land.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I am a big fan of Vue and cannot breathe without static sites. So, it is only natural that I play around and implement Vue-based static sites for fun and profit.</p>
<p>Here&rsquo;s a distilled-down version of my experience with <a href="https://vuepress.vuejs.org/">Vuepress</a>.</p>
<h2 id="the-situation">The Situation</h2>
<p>I create static sites that are &ldquo;real&rdquo; websites. Typically the following factors in a static site generator help -</p>
<ol>
<li>A cool, easy-to-customise home page</li>
<li>Themes/starter projects that make life easy</li>
<li>Plugins that can extend functionality of core software</li>
</ol>
<p>Although I had played around Vuepress quite a bit, I always ended up choosing non-Vue technologies like Hugo, or Vue-based static site generators like Gridsome or Saber.land.</p>
<p>More recently however, I decided to have this long drawn out project to create a free tutorial website. With great delight and big plans, I chose Vuepress.</p>
<p>This is that true story.</p>
<h2 id="what-exactly-is-vuepress">What exactly is Vuepress?</h2>
<p>A Vue-based static site generator, which is created by Evan Yu and supported by the Vue team. If that is not enough to get you going, there are other factors too. Read on.</p>
<p>Vuepress was created for documentation sites but has official themes/plugins to create a blog as well.</p>
<ul>
<li>Create documentation sites</li>
<li>Create full-scale websites (we will get back to this point)</li>
<li>Create blogs</li>
<li>Create eCommerce sites</li>
<li>Make sites interactive with the power of Vue</li>
</ul>
<p>Vuepress is simple, provides a standard experience, (kind of) easy to configure and easy to get started.</p>
<h2 id="getting-started-on-vuepress">Getting Started on Vuepress</h2>
<p>Create a project folder and install Vuepress.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl"><span class="k">mkdir</span> awedocs
</span></span><span class="line"><span class="cl"><span class="k">cd</span> awedocs
</span></span><span class="line"><span class="cl">yarn init
</span></span><span class="line"><span class="cl">yarn add -D vuepress
</span></span></code></pre></div><p>And then.. be prepared to act surprised - because there is nothing really there. There is little to see fresh out of the box. We need a few more steps to get there.</p>
<p>Open the <code>awedocs</code> folder in your VSCode. Create a sub directory called <code>docs</code> in the root folder. Then, create a file named <code>README.md</code> in <code>docs</code> folder. Enter following content in the file..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl">Hello world
</span></span></code></pre></div><p><code>md</code> or markdown files will contain the content of your site. This file should be good for initial tests.</p>
<p>Open <code>package.json</code> and enter scripts to run Vuepress. Your entire file may look like below -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;awedocs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Awesome docs.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;scripts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;dev&#34;</span><span class="p">:</span> <span class="s2">&#34;vuepress dev docs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;build&#34;</span><span class="p">:</span> <span class="s2">&#34;vuepress build docs&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;main&#34;</span><span class="p">:</span> <span class="s2">&#34;index.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;repository&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/techformist/awedocs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;author&#34;</span><span class="p">:</span> <span class="s2">&#34;Prashanth Krishnamurthy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;license&#34;</span><span class="p">:</span> <span class="s2">&#34;MIT&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;devDependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;vuepress&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.2&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Go back to command prompt, and issue the command ..</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">yarn dev
</span></span></code></pre></div><p><img loading="lazy" src="/misc/vuepress-dev-start.png" type="" alt="vuepress-dev-start"  /></p>
<p>.. and ta da - you have your Vuepress site up and running.</p>
<p><img loading="lazy" src="/misc/default-site-vuepress.png" type="" alt="default-site-vuepress"  /></p>
<p>You can make a few smart observations -</p>
<ol>
<li>Vuepress is minimal (at least in the beginning)</li>
<li>Vuepress comes with a default theme</li>
<li>Content and presentation layer is well isolated with the presentation layer</li>
</ol>
<p>This means that -</p>
<ol>
<li>you can get started really really quickly. Install Vuepress -&gt; start creating documents / blog posts</li>
<li>you don&rsquo;t need to learn Vue/Vuepress to use Vuepress to create a documentation site or blog</li>
</ol>
<h2 id="making-vuepress-your-own">Making Vuepress your own</h2>
<p>The site generated so far is functional but too minimal. Let&rsquo;s add some jazz.</p>
<p>Update <code>README.md</code> with following content -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">home: true
</span></span><span class="line"><span class="cl">heroImage: /images/dog.jpg
</span></span><span class="line"><span class="cl">heroText: Awedocs
</span></span><span class="line"><span class="cl">tagline: docs. docs. docs.
</span></span><span class="line"><span class="cl">actionText: Get Started →
</span></span><span class="line"><span class="cl">actionLink: /more
</span></span><span class="line"><span class="cl">features:
</span></span><span class="line"><span class="cl">  <span class="k">-</span> title: Good
</span></span><span class="line"><span class="cl">    details: Know everything.
</span></span><span class="line"><span class="cl">  <span class="k">-</span> title: Better
</span></span><span class="line"><span class="cl">    details: Know something.
</span></span><span class="line"><span class="cl">  <span class="k">-</span> title: Best
</span></span><span class="line"><span class="cl">    details: Know nothing.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">footer: MIT Licensed
</span></span><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gh"># Hello world!
</span></span></span></code></pre></div><p>The content between <code>---</code> is called frontmatter. This tells Vuepress to mete out some special treatment to the file.</p>
<p>Now do two things to support above content -</p>
<ol>
<li>
<p>Add a file called <code>more.md</code> alongside <code>README.md</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gh"># Morrreee
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is much more information than I can handle.
</span></span></code></pre></div></li>
<li>
<p>Create a new folder <code>/docs/.vuepress/images</code>. Save a sample image and name it <code>dog.jpg</code>.</p>
</li>
</ol>
<p>Stop Vuepress dev server. Start it again.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">yarn dev
</span></span></code></pre></div><p>You have something that resembles a typical website.</p>
<p><img loading="lazy" src="/misc/start-page-with-frontmatter-vuepress.png" type="" alt="start-page-with-frontmatter-vuepress"  /></p>
<p>The <code>/docs/.vuepress</code> folder will have any and all customisations for your Vuepress instance. This includes -</p>
<ul>
<li>Vue Components</li>
<li>Navigation bars</li>
<li>Additional Javascript</li>
<li>Styles</li>
</ul>
<p>Content stays in the <code>/docs</code> folder.</p>
<h2 id="add-more-ui-elements">Add more UI elements</h2>
<p>Lets add a sidebar and navbar.</p>
<p>Create a file called <code>/docs/.vuepress/config.js</code>, which will house all the configuration for Vuepress. Introduce following content in the file -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">base</span><span class="o">:</span> <span class="s2">&#34;/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;awedocs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">description</span><span class="o">:</span> <span class="s2">&#34;Awesome docs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">themeConfig</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">label</span><span class="o">:</span> <span class="s2">&#34;English&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">editLinkText</span><span class="o">:</span> <span class="s2">&#34;Edit this page on GitHub&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">lastUpdated</span><span class="o">:</span> <span class="s2">&#34;Last Updated&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">nav</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;./nav&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">sidebar</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Home&#34;</span><span class="p">,</span> <span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;&#34;</span><span class="p">]</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Misc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;more&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nx">repo</span><span class="o">:</span> <span class="s2">&#34;techformist/awedocs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">editLinks</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">plugins</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;@vuepress/back-to-top&#34;</span><span class="o">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Create a file called <code>.vuepress/nav.js</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">text</span><span class="o">:</span> <span class="s2">&#34;Let Me Google&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">link</span><span class="o">:</span> <span class="s2">&#34;https://google.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">text</span><span class="o">:</span> <span class="s2">&#34;About&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">items</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nx">text</span><span class="o">:</span> <span class="s2">&#34;About&#34;</span><span class="p">,</span> <span class="nx">link</span><span class="o">:</span> <span class="s2">&#34;/about&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nx">text</span><span class="o">:</span> <span class="s2">&#34;Terms&#34;</span><span class="p">,</span> <span class="nx">link</span><span class="o">:</span> <span class="s2">&#34;/terms&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span></code></pre></div><p>Restart Vuepress to see this -</p>
<p><img loading="lazy" src="/misc/vuepress-site-navbar-sidebar.gif" type="" alt="vuepress-site-navbar-sidebar"  /></p>
<h2 id="build-and-deploy">Build and Deploy</h2>
<p>Once you are ready, you do a simple -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">yarn build
</span></span></code></pre></div><p>This will create a <code>docs/.vuepress/dist</code> folder. Upload this folder to your host and you are done!</p>
<h2 id="what-could-i-do-next">What could I do next?</h2>
<p>Well, sky&rsquo;s the limit. Vuepress is based off Vue and Javascript - so you can do nothing short of magic.</p>
<p>There are a few things that can be highlighted here -</p>
<h3 id="1-add-simple-vue-components-and-interactivity">1. Add simple Vue components and interactivity</h3>
<p>We can include interactive components in markdown.</p>
<p>Create a Vue component called <code>AddNum.vue</code> in <code>docs/.vuepress/components/</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;a&#34;</span><span class="p">&gt;</span>Num 1<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">input</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;a&#34;</span> <span class="na">v-model</span><span class="o">=</span><span class="s">&#34;a&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;number&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;b&#34;</span><span class="p">&gt;</span>Num 2<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">input</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;a&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;number&#34;</span> <span class="na">v-model</span><span class="o">=</span><span class="s">&#34;b&#34;</span> <span class="na">align</span><span class="o">=</span><span class="s">&#34;right&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;font-weight:bold; margin-top:15px&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">&#34;sum&#34;</span><span class="p">&gt;</span>Sum =<span class="p">&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">input</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;sum&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;number&#34;</span> <span class="na">:value</span><span class="o">=</span><span class="s">&#34;sum&#34;</span> <span class="na">align</span><span class="o">=</span><span class="s">&#34;right&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">data</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">a</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">b</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">computed</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">sum</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">+</span><span class="k">this</span><span class="p">.</span><span class="nx">a</span> <span class="o">+</span> <span class="o">+</span><span class="k">this</span><span class="p">.</span><span class="nx">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">style</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;css&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">input</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">text-align</span><span class="p">:</span> <span class="kc">center</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">style</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Include this component in <code>more.md</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gh"># Morrreee
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is much more information than I can handle.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">But, I could do a sum for you.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;AddNum/&gt;
</span></span></code></pre></div><p>See the magic of adding numbers on the fly.</p>
<h3 id="create-even-more-complex-components">Create even more complex components</h3>
<p>Let us have a Vue gallery for our glorious site.</p>
<p>In the root folder do an install.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">yarn add vue-gallery
</span></span></code></pre></div><p>Create <code>/docs/.vuepress/Galleria.vue</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="c">&lt;!-- code from https://www.npmjs.com/package/vue-gallery --&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;padme&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">gallery</span> <span class="na">:images</span><span class="o">=</span><span class="s">&#34;images&#34;</span> <span class="na">:index</span><span class="o">=</span><span class="s">&#34;index&#34;</span> <span class="err">@</span><span class="na">close</span><span class="o">=</span><span class="s">&#34;index = null&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">gallery</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span>
</span></span><span class="line"><span class="cl">      <span class="na">class</span><span class="o">=</span><span class="s">&#34;image&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">v-for</span><span class="o">=</span><span class="s">&#34;(image, imageIndex) in images&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:key</span><span class="o">=</span><span class="s">&#34;imageIndex&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="err">@</span><span class="na">click</span><span class="o">=</span><span class="s">&#34;index = imageIndex&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:style</span><span class="o">=</span><span class="s">&#34;{
</span></span></span><span class="line"><span class="cl"><span class="s">        backgroundImage: &#39;url(&#39; + image + &#39;)&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        width: &#39;300px&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        height: &#39;200px&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">      }&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">import</span> <span class="nx">VueGallery</span> <span class="nx">from</span> <span class="s2">&#34;vue-gallery&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">data</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">images</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;https://dummyimage.com/800/ffffff/000000&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;https://dummyimage.com/1600/ffffff/000000&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;https://dummyimage.com/1280/000000/ffffff&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;https://dummyimage.com/400/000000/ffffff&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nx">index</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">gallery</span><span class="o">:</span> <span class="nx">VueGallery</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">style</span> <span class="na">scoped</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nc">image</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">float</span><span class="p">:</span> <span class="k">clear</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">background-size</span><span class="p">:</span> <span class="kc">cover</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">background-repeat</span><span class="p">:</span> <span class="kc">no-repeat</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">background-position</span><span class="p">:</span> <span class="kc">center</span> <span class="kc">center</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">border</span><span class="p">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="kc">solid</span> <span class="mh">#ebebeb</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">margin</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nc">padme</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">padding-top</span><span class="p">:</span> <span class="mf">2.5</span><span class="kt">em</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">padding-bottom</span><span class="p">:</span> <span class="mf">2.5</span><span class="kt">em</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">style</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Include this component in our <code>more.md</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gh"># Morrreee
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is much more information than I can handle.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Sum
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">But, I could do a sum for you.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;AddNum/&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Gallery
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Or, I could show a gallery. Click on the image to view full screen.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;Galleria/&gt;
</span></span></code></pre></div><p>You have a fully functioning gallery!</p>
<p>Note that we did not add this component anywhere other than creating a <code>vue</code> file, nor did we <code>use</code> the component.</p>
<h3 id="3-use-a-vue-plugin">3. Use a Vue plugin</h3>
<p>Since Vuepress has Vue behind the scenes, we could hop on to the same magic train for our own nefarious schemes.</p>
<p>Do yet another install.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">yarn add vue-typed-js
</span></span></code></pre></div><p>Create a new Vue file - <code>/docs/.vuepress/components/</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">vue-typed-js</span>
</span></span><span class="line"><span class="cl">      <span class="na">:strings</span><span class="o">=</span><span class="s">&#34;[
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;once&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;twice&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;thrice&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;four times&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;five times&#39;,
</span></span></span><span class="line"><span class="cl"><span class="s">        &#39;infinity&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">      ]&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">:loop</span><span class="o">=</span><span class="s">&#34;true&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">h4</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;color:red&#34;</span><span class="p">&gt;</span>Going.. <span class="p">&lt;</span><span class="nt">span</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;typing&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">span</span><span class="p">&gt;&lt;/</span><span class="nt">h4</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">vue-typed-js</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Again, add this new component to our <code>more.md</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gh"># Morrreee
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is much more information than I can handle.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Sum
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">But, I could do a sum for you.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;AddNum/&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Gallery
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Or, I could show a gallery. Click on the image to view full screen.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;Galleria/&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Typing Ahoy
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">I could even show this cool type simulator.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">&lt;TypeAhoy/&gt;
</span></span></code></pre></div><p>You now have some typing magic :)</p>
<p><img loading="lazy" src="/misc/vuepress-interactivity-vue-components.gif" type="" alt="vuepress-interactivity-vue-components"  /></p>
<h2 id="custom-themes-and-plugins">Custom themes and plugins</h2>
<p>So far you have seen themes provided by default in Vuepress. You can extend the theme or use a theme developed by third parties.</p>
<p>Similarly, you can develop custom functionality using plugins. Vuepress provides a number of core-team and community maintained plugins that do everything from enabling a blog on your site to creating a sitemap, creating diagrams using MermaidJS, or displaying your content as a presentation.</p>
<p>See themes and plugins listed on <a href="https://vuepress.tools/">Vuepress.tools</a>.</p>
<h2 id="that-was-easy-time-to-go-crazy">That was easy. Time to go crazy?</h2>
<p>Well, it depends. Vuepress has its positives and not-so-positives.</p>
<p>For starters -</p>
<ol>
<li>Vuepress is easy to get started with. It&rsquo;s out-of-box theme is great and anyone can get started in no time</li>
<li>Provides a great user experience (similar to a single page app)</li>
<li>It is easy to understand for non-techies. Provides a good isolation b/w content creation and presentation layers</li>
<li>Has the full power of Vue behind it - you can provide super interactivity using Vue components and plugins</li>
<li>Theming is quite strong</li>
<li>It has some good plugins. You can also roll out your own plugin quite easily</li>
</ol>
<p>On the other hand..</p>
<ol>
<li>Is not as flexible as more developer-friendly solutions like Gridsome. Yes, this is opinionated and YMMV</li>
<li>I struggled a bit to implement adhoc taxonomies</li>
<li>With dependency on Webpack, it does not lend itself well for lot of content</li>
<li>It has a big initial payload, which is increasingly viewed as something that we live with (but wanted to mention it anyway)</li>
</ol>
<p>Starting a documentation site and using a couple of plugins was easy enough, but my experience customising Vuepress was not that great (again, this is a &lsquo;me&rsquo; experience). I found Gridsome or Saber.land easier to understand and customise to my heart&rsquo;s content.</p>
<p>That said, I will probably use Vuetify for all the documentation sites going forward since it is quite simple and fast to get started with.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Simple Site Summary in Hugo</title>
      <link>https://techformist.com/simple-site-summary-hugo/</link>
      <pubDate>Mon, 25 Nov 2019 18:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/simple-site-summary-hugo/</guid>
      <description>&lt;p&gt;Here&amp;rsquo;s a simple way to organize your taxonomies and have a bird&amp;rsquo;s eye view of the number of posts per category/tag in Hugo.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;As techformist.com grew, I became more and more disorganised in maintaining taxonomies. I had some interesting situations -&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &amp;ldquo;static-site&amp;rdquo; category coexist with &amp;ldquo;static sites&amp;rdquo; category&lt;/li&gt;
&lt;li&gt;confusion b/w why I chose a few terms to be tags rather than categories in their own right&lt;/li&gt;
&lt;li&gt;the recurring need to &amp;ldquo;rethink taxonomy structure&amp;rdquo; depending on the flavour of the month and time of the day&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This often required me to go back and change a few taxonomy terms, or to reorganize site structure in order to provide better visibility to chosen topics.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Here&rsquo;s a simple way to organize your taxonomies and have a bird&rsquo;s eye view of the number of posts per category/tag in Hugo.</p>
<h2 id="the-problem">The Problem</h2>
<p>As techformist.com grew, I became more and more disorganised in maintaining taxonomies. I had some interesting situations -</p>
<ul>
<li>a &ldquo;static-site&rdquo; category coexist with &ldquo;static sites&rdquo; category</li>
<li>confusion b/w why I chose a few terms to be tags rather than categories in their own right</li>
<li>the recurring need to &ldquo;rethink taxonomy structure&rdquo; depending on the flavour of the month and time of the day</li>
</ul>
<p>This often required me to go back and change a few taxonomy terms, or to reorganize site structure in order to provide better visibility to chosen topics.</p>
<p>I also developed this habit of referring back to the older topics with a site search / VSCode search just to copy/paste tags and categories from an older post.</p>
<p>This was frustrating.</p>
<h2 id="the-solution">The Solution</h2>
<p>There were couple of simple solution options -</p>
<ol>
<li>Create a summary page on the site</li>
<li>Include counts in the manually maintained writing/editorial calendar (and bring some automation to that side of the world while at it)</li>
<li>Analyse sitemap to get a nice summary and maintain that analysis somewhere</li>
</ol>
<p>In the end, I felt it would be easier to create a quick summary page on the site and refer back to it, rather than over-engineer a solution.</p>
<p>So, I created this summary page with just a few lines of code for layout.</p>
<p><img loading="lazy" src="/misc/hugo-site-summary.jpg" type="" alt="hugo-summary-count-posts-categories-tags"  /></p>
<p>I can now -</p>
<ol>
<li>Quickly check the categories / tags and select relevant combination for a new post</li>
<li>Keep an eye on the counts and refocus on things that I have to write more about</li>
<li>Satisfy my ego by showing the post counts and by hiding away more useful statistics such as the usefulness &amp; longevity of the content</li>
</ol>
<h2 id="how-to-implement-this-in-your-own-hugo-site">How to implement this in your own Hugo site?</h2>
<p>Create a file called &ldquo;summary.html&rdquo; in your <code>layouts</code> folder.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{ partial &#34;header&#34; . }} 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{ partial &#34;header/header&#34; . }}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{/*-- post count */}}
</span></span><span class="line"><span class="cl">{{ $posts := (where .Site.RegularPages &#34;Section&#34; &#34;==&#34; &#34;posts&#34;) }}
</span></span><span class="line"><span class="cl">{{ $postCount := len $posts }}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{/*-- page count */}}
</span></span><span class="line"><span class="cl">{{ $pages := (where .Site.RegularPages &#34;Section&#34; &#34;==&#34; &#34;page&#34;) }}
</span></span><span class="line"><span class="cl">{{ $pageCount := len $pages }}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">div</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;overflow: auto;&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">td</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;text-align:center;font-weight: bold;width: 10em;&#34;</span><span class="p">&gt;</span>Description<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">td</span> <span class="na">style</span><span class="o">=</span><span class="s">&#34;text-align:center;font-weight: bold;&#34;</span><span class="p">&gt;</span>Value<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>Pages<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>{{ $pageCount }}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>Posts<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>{{ $postCount }}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>Post by Categories<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          {{ range $name, $taxonomy := .Site.Taxonomies.categories }}
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/categories/{{ $name | urlize }}&#34;</span><span class="p">&gt;</span>{{ $name | humanize }} ({{ $taxonomy.Count }})<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="ni">&amp;nbsp;</span>
</span></span><span class="line"><span class="cl">          {{end}}
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;</span>Post by Tags<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          {{ range $name, $taxonomy := .Site.Taxonomies.tags }}
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/tags/{{ $name | urlize }}&#34;</span><span class="p">&gt;</span>#{{ $name | humanize }} ({{ $taxonomy.Count }})<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="ni">&amp;nbsp;</span>
</span></span><span class="line"><span class="cl">          {{end}}
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{ partial &#34;footer&#34; . }}
</span></span></code></pre></div><p>As you can see, I am no where near an expert on Hugo. Or, even basic styling in HTML :)</p>
<p>Next, create a content page in <code>pages</code> folder. This is to better organize structure in the future.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: Summary of Posts
</span></span><span class="line"><span class="cl">url: summary
</span></span><span class="line"><span class="cl">type: page
</span></span><span class="line"><span class="cl">layout: summary
</span></span><span class="line"><span class="cl">date: 2020-02-20 20:20:20
</span></span><span class="line"><span class="cl">comments: false
</span></span><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is a summary of the site that lists categories, tags and what not alongside the number of posts. Not quite useful for anyone other than the publishers.
</span></span></code></pre></div><p>Navigate to <code>&lt;your site&gt;/summary</code>.</p>
<p>Have fun.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Include full content in site feed in Hugo</title>
      <link>https://techformist.com/full-post-feed-hugo/</link>
      <pubDate>Thu, 17 Oct 2019 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/full-post-feed-hugo/</guid>
      <description>&lt;p&gt;Include all content of your posts in your site feed when using Hugo static site generator.&lt;/p&gt;
&lt;p&gt;By default Hugo will include only summary in your website feed (e.g. in &lt;code&gt;/index.xml&lt;/code&gt;). Your theme may already provide a way to provide full content instead of just the summary. If it doesn&amp;rsquo;t, you can make those simple changes yourself.&lt;/p&gt;
&lt;p&gt;Create a new file &lt;code&gt;rss.xml&lt;/code&gt; in &lt;code&gt;layouts\_default\&lt;/code&gt; folder in your site root directory. Include following content (as of v0.58) -&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Include all content of your posts in your site feed when using Hugo static site generator.</p>
<p>By default Hugo will include only summary in your website feed (e.g. in <code>/index.xml</code>). Your theme may already provide a way to provide full content instead of just the summary. If it doesn&rsquo;t, you can make those simple changes yourself.</p>
<p>Create a new file <code>rss.xml</code> in <code>layouts\_default\</code> folder in your site root directory. Include following content (as of v0.58) -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="c">&lt;!-- layouts\_default\rss.xml --&gt;</span>
</span></span><span class="line"><span class="cl">{{ printf &#34;<span class="cp">&lt;?xml version=\&#34;1.0\&#34; encoding=\&#34;utf-8\&#34; standalone=\&#34;yes\&#34; ?&gt;</span>&#34; | safeHTML }}
</span></span><span class="line"><span class="cl"><span class="nt">&lt;rss</span> <span class="na">version=</span><span class="s">&#34;2.0&#34;</span> <span class="na">xmlns:atom=</span><span class="s">&#34;http://www.w3.org/2005/Atom&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;channel&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;title&gt;</span>{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}<span class="nt">&lt;/title&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;link&gt;</span>{{ .Permalink }}<span class="nt">&lt;/link&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;description&gt;</span>Recent content {{ if ne  .Title  .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}<span class="nt">&lt;/description&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;generator&gt;</span>Hugo -- gohugo.io<span class="nt">&lt;/generator&gt;</span>{{ with .Site.LanguageCode }}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;language&gt;</span>{{.}}<span class="nt">&lt;/language&gt;</span>{{end}}{{ with .Site.Author.email }}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;managingEditor&gt;</span>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}<span class="nt">&lt;/managingEditor&gt;</span>{{end}}{{ with .Site.Author.email }}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;webMaster&gt;</span>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}<span class="nt">&lt;/webMaster&gt;</span>{{end}}{{ with .Site.Copyright }}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;copyright&gt;</span>{{.}}<span class="nt">&lt;/copyright&gt;</span>{{end}}{{ if not .Date.IsZero }}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;lastBuildDate&gt;</span>{{ .Date.Format &#34;2006-01-02&#34; | safeHTML }}<span class="nt">&lt;/lastBuildDate&gt;</span>{{ end }}
</span></span><span class="line"><span class="cl">    {{ with .OutputFormats.Get &#34;RSS&#34; }}
</span></span><span class="line"><span class="cl">        {{ printf &#34;<span class="nt">&lt;atom:link</span> <span class="na">href=</span><span class="s">%q</span> <span class="na">rel=</span><span class="s">\&#34;self\&#34;</span> <span class="na">type=</span><span class="s">%q</span> <span class="nt">/&gt;</span>&#34; .Permalink .MediaType | safeHTML }}
</span></span><span class="line"><span class="cl">    {{ end }}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    {{- range first 10 (where .Site.RegularPages &#34;Type&#34; &#34;not in&#34; &#34;pages&#34; ) -}}
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;item&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;title&gt;</span>{{ .Title }}<span class="nt">&lt;/title&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;link&gt;</span>{{ .Permalink }}<span class="nt">&lt;/link&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;pubDate&gt;</span>{{ .Date.Format &#34;2006-01-02&#34; | safeHTML }}<span class="nt">&lt;/pubDate&gt;</span>
</span></span><span class="line"><span class="cl">      {{ with .Site.Author.email }}<span class="nt">&lt;author&gt;</span>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}<span class="nt">&lt;/author&gt;</span>{{end}}
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;guid&gt;</span>{{ .Permalink }}<span class="nt">&lt;/guid&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;description&gt;</span>{{ .Content | html }}<span class="nt">&lt;/description&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/item&gt;</span>
</span></span><span class="line"><span class="cl">    {{ end }}
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/channel&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/rss&gt;</span>
</span></span></code></pre></div><p>The content of the file is almost same as the <a href="https://gohugo.io/templates/rss/#the-embedded-rss-xml">embedded <code>rss.xml</code> used in Hugo</a>.</p>
<p>.. except for two crucial differences -</p>
<ol>
<li>
<p>Include full content in RSS feed</p>
<pre tabindex="0"><code>&lt;description&gt;{{ .Content | html }}&lt;/description&gt;
</code></pre></li>
<li>
<p>Fetch only 10 articles in the feed. You can get this 10 from the site config as well.</p>
<pre tabindex="0"><code>{{- range first 10 (where .Site.RegularPages &#34;Type&#34; &#34;not in&#34; &#34;pages&#34; ) -}}
</code></pre></li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>Add PWA to your Hugo site</title>
      <link>https://techformist.com/add-pwa-hugo/</link>
      <pubDate>Wed, 11 Sep 2019 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/add-pwa-hugo/</guid>
      <description>&lt;p&gt;Adding PWA to your Hugo static site is quite easy.&lt;/p&gt;
&lt;h3 id=&#34;what-is-pwa-and-why-should-i-add-it&#34;&gt;What is PWA and why should I add it?&lt;/h3&gt;
&lt;p&gt;Progressive web applications (PWA) are a nice way to give your websites an &amp;ldquo;app makeover&amp;rdquo;. Using PWAs your sites are perceived to load faster, are available offline, and in general improve user experience.&lt;/p&gt;
&lt;p&gt;PWAs are supported by all web browsers. Using PWAs on single page applications have shown remarkable improvement in site speed and have provided us the ability to continuing to serve static content even when the connectivity is down.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Adding PWA to your Hugo static site is quite easy.</p>
<h3 id="what-is-pwa-and-why-should-i-add-it">What is PWA and why should I add it?</h3>
<p>Progressive web applications (PWA) are a nice way to give your websites an &ldquo;app makeover&rdquo;. Using PWAs your sites are perceived to load faster, are available offline, and in general improve user experience.</p>
<p>PWAs are supported by all web browsers. Using PWAs on single page applications have shown remarkable improvement in site speed and have provided us the ability to continuing to serve static content even when the connectivity is down.</p>
<p>Back to Hugo - although I can see incremental gains, nothing jumped out to make up for a compelling case for PWA. The sites generated by Hugo are static - pages are already generated and waiting to be loaded. Depending on the theme, you may already be seeing the best load times that your site can achieve. So, YMMV.</p>
<h3 id="how-do-i-add-pwa-to-hugo">How do I add PWA to Hugo?</h3>
<p>At a minimum a PWA needs a manifest and service worker. We will use a offline-first cache strategy to enable PWA.</p>
<h5 id="create-your-icons">Create your icons</h5>
<p>PWAs are available offline and can be installed on the phone. This requires icons of different sizes for your website. Just pluck your logo, remove the text if necessary and generate icons of all popular sizes. You can use a service like <a href="https://favicomatic.com/">Favicomatic</a> to make that a one-click process.</p>
<h5 id="create-manifest">Create manifest</h5>
<p>Create a new file called <code>manifest.json</code> in your <code>/static</code> folder and add content similar to below</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Techformist&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;short_name&#34;</span><span class="p">:</span> <span class="s2">&#34;techformist&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;icons&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;src&#34;</span><span class="p">:</span> <span class="s2">&#34;/appicons/favicon-128.png&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sizes&#34;</span><span class="p">:</span> <span class="s2">&#34;128x128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;image/png&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;src&#34;</span><span class="p">:</span> <span class="s2">&#34;/appicons/apple-touch-icon-144x144.png&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sizes&#34;</span><span class="p">:</span> <span class="s2">&#34;144x144&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;image/png&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;src&#34;</span><span class="p">:</span> <span class="s2">&#34;/appicons/apple-touch-icon-152x152.png&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sizes&#34;</span><span class="p">:</span> <span class="s2">&#34;152x152&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;image/png&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;src&#34;</span><span class="p">:</span> <span class="s2">&#34;/appicons/favicon-196x196.png&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sizes&#34;</span><span class="p">:</span> <span class="s2">&#34;196x196&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;image/png&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;src&#34;</span><span class="p">:</span> <span class="s2">&#34;/appicons/splash.png&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sizes&#34;</span><span class="p">:</span> <span class="s2">&#34;512x512&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;image/png&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;start_url&#34;</span><span class="p">:</span> <span class="s2">&#34;/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;display&#34;</span><span class="p">:</span> <span class="s2">&#34;standalone&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;orientation&#34;</span><span class="p">:</span> <span class="s2">&#34;portrait&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;background_color&#34;</span><span class="p">:</span> <span class="s2">&#34;#FFFFFF&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;theme_color&#34;</span><span class="p">:</span> <span class="s2">&#34;#FFFFFF&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h5 id="create-service-worker">Create service worker</h5>
<p>Create a new javascript file <code>sw.js</code> in <code>/static</code>. This script does all the heavy lifting like maintaining cache and enabling your site to be treated like an app.</p>
<p>I just copied the code from the sample service worker script available at [https://github.com/wildhaber/offline-first-sw].</p>
<p>Modify the file and choose to make some or all files available offline - I typically include CSS, common Javascript files and images. See the end of this article for the file used by this blog.</p>
<h5 id="include-manifest-in-head">Include manifest in <code>head</code></h5>
<p>Include a link to your manifest in your header.</p>
<p>I use Minimo theme and included the following line in <code>&lt;root&gt;/layouts/partials/head/extra.html</code>. Note that I am not over-writing the file in the theme folder, but overriding it using my own version (as is typical to Hugo themes).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;manifest&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/manifest.json&#34;</span><span class="p">&gt;</span>
</span></span></code></pre></div><h5 id="include-sw-in-footer">Include SW in footer</h5>
<p>Include the service worker JS file reference in your footer. For some strange reason, I chose to be different and included that in my <code>sidebar.html</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span><span class="p">(</span><span class="s1">&#39;serviceWorker&#39;</span> <span class="k">in</span> <span class="nx">navigator</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigator</span><span class="p">.</span><span class="nx">serviceWorker</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="nx">register</span><span class="p">(</span><span class="s1">&#39;/sw.js&#39;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">scope</span><span class="o">:</span> <span class="s1">&#39;/&#39;</span> <span class="p">})</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">registration</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="c1">//console.log(&#39;Service Worker Registered&#39;);
</span></span></span><span class="line"><span class="cl">          <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="nx">navigator</span><span class="p">.</span><span class="nx">serviceWorker</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="nx">ready</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">registration</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="c1">//console.log(&#39;Service Worker Ready&#39;);
</span></span></span><span class="line"><span class="cl">          <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><h3 id="see-the-results">See the Results</h3>
<p>That is it. Your site automagically is a PWA now.</p>
<p>Check out Chrome developer tools -</p>
<h5 id="a-site-or-an-app">A site or an app?</h5>
<p>Go to <code>Application</code> tab.</p>
<p>You should see details provided in your manifest including the different icons. You will also see the different offline files you specified in the <code>Cache Storage</code> section.</p>
<h5 id="lighthouse-scores">Lighthouse scores</h5>
<p>Go to <code>Audit</code> tab and do a Lighthouse audit for your site.</p>
<p>Mobile Lighthouse score for home page -</p>
<p><img loading="lazy" src="/misc/lighthouse-score-home-page.jpg" type="" alt="lighthouse-score-home-page"  /></p>
<p>Lighthouse score for an article -</p>
<p><img loading="lazy" src="/misc/lighthouse-score-article.jpg" type="" alt="lighthouse-score-article"  /></p>
<p>Rejoice.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Adding and setting up PWA to Hugo is trivial. But, I did not clearly make out any significant advantages of enabling PWA on my blog - given that I am not after providing a read-offline feature.</p>
<h3 id="post-script">Post Script</h3>
<h5 id="swjs-code">sw.js code</h5>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CACHE_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">BASE_CACHE_FILES</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/css/custom.css&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/js/custom.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/search/index.json&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/manifest.json&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/favicon.png&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/images/logo.png&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/techformist-logo-no-text.png&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/css/main.6a060eb7.css&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/main.67d669ac.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/sidebar.9ea42a6e.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/fuse_search.1ada4bca.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">OFFLINE_CACHE_FILES</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/images/logo.png&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/techformist-logo-no-text.png&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/css/main.6a060eb7.css&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/main.67d669ac.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/sidebar.9ea42a6e.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/assets/js/fuse_search.1ada4bca.js&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">NOT_FOUND_CACHE_FILES</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/404.html&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">OFFLINE_PAGE</span> <span class="o">=</span> <span class="s1">&#39;/offline/index.html&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">NOT_FOUND_PAGE</span> <span class="o">=</span> <span class="s1">&#39;/404.html&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CACHE_VERSIONS</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assets</span><span class="o">:</span> <span class="s1">&#39;assets-v&#39;</span> <span class="o">+</span> <span class="nx">CACHE_VERSION</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s1">&#39;content-v&#39;</span> <span class="o">+</span> <span class="nx">CACHE_VERSION</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">offline</span><span class="o">:</span> <span class="s1">&#39;offline-v&#39;</span> <span class="o">+</span> <span class="nx">CACHE_VERSION</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">notFound</span><span class="o">:</span> <span class="s1">&#39;404-v&#39;</span> <span class="o">+</span> <span class="nx">CACHE_VERSION</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Define MAX_TTL&#39;s in SECONDS for specific file extensions
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">MAX_TTL</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;/&#39;</span><span class="o">:</span> <span class="mi">3600</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">html</span><span class="o">:</span> <span class="mi">3600</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">json</span><span class="o">:</span> <span class="mi">86400</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">js</span><span class="o">:</span> <span class="mi">86400</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">css</span><span class="o">:</span> <span class="mi">86400</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CACHE_BLACKLIST</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">       <span class="k">return</span> <span class="o">!</span><span class="nx">str</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="s1">&#39;http://localhost&#39;</span><span class="p">)</span> <span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">SUPPORTED_METHODS</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * isBlackListed
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {string} url
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {boolean}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">isBlacklisted</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="nx">CACHE_BLACKLIST</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">?</span> <span class="o">!</span><span class="nx">CACHE_BLACKLIST</span><span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">rule</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="k">typeof</span> <span class="nx">rule</span> <span class="o">===</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="o">!</span><span class="nx">rule</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}).</span><span class="nx">length</span> <span class="o">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * getFileExtension
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {string} url
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {string}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getFileExtension</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">extension</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">).</span><span class="nx">reverse</span><span class="p">()[</span><span class="mi">0</span><span class="p">].</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;?&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="nx">extension</span><span class="p">.</span><span class="nx">endsWith</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">))</span> <span class="o">?</span> <span class="s1">&#39;/&#39;</span> <span class="o">:</span> <span class="nx">extension</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * getTTL
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {string} url
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getTTL</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">url</span> <span class="o">===</span> <span class="s1">&#39;string&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">let</span> <span class="nx">extension</span> <span class="o">=</span> <span class="nx">getFileExtension</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">MAX_TTL</span><span class="p">[</span><span class="nx">extension</span><span class="p">]</span> <span class="o">===</span> <span class="s1">&#39;number&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="nx">MAX_TTL</span><span class="p">[</span><span class="nx">extension</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * installServiceWorker
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {Promise}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">installServiceWorker</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">assets</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">cache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="k">return</span> <span class="nx">cache</span><span class="p">.</span><span class="nx">addAll</span><span class="p">(</span><span class="nx">BASE_CACHE_FILES</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">offline</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">cache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="k">return</span> <span class="nx">cache</span><span class="p">.</span><span class="nx">addAll</span><span class="p">(</span><span class="nx">OFFLINE_CACHE_FILES</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">notFound</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">cache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="k">return</span> <span class="nx">cache</span><span class="p">.</span><span class="nx">addAll</span><span class="p">(</span><span class="nx">NOT_FOUND_CACHE_FILES</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * cleanupLegacyCache
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {Promise}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">cleanupLegacyCache</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">currentCaches</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">.</span><span class="nx">map</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="nx">CACHE_VERSIONS</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="nx">caches</span><span class="p">.</span><span class="nx">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">keys</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="k">return</span> <span class="nx">legacyKeys</span> <span class="o">=</span> <span class="nx">keys</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                            <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                <span class="k">return</span> <span class="o">!~</span><span class="nx">currentCaches</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                            <span class="p">}</span>
</span></span><span class="line"><span class="cl">                        <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">legacy</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="k">if</span> <span class="p">(</span><span class="nx">legacy</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                            <span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                <span class="nx">legacy</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">(</span><span class="nx">legacyKey</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="k">return</span> <span class="nx">caches</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">legacyKey</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                <span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="nx">resolve</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="nx">reject</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                <span class="p">);</span>
</span></span><span class="line"><span class="cl">                        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                            <span class="nx">resolve</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                        <span class="p">}</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nx">reject</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">self</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;install&#39;</span><span class="p">,</span> <span class="nx">event</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">event</span><span class="p">.</span><span class="nx">waitUntil</span><span class="p">(</span><span class="nx">installServiceWorker</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// The activate handler takes care of cleaning up old caches.
</span></span></span><span class="line"><span class="cl"><span class="nx">self</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;activate&#39;</span><span class="p">,</span> <span class="nx">event</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">event</span><span class="p">.</span><span class="nx">waitUntil</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="nb">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                <span class="p">[</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">cleanupLegacyCache</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="p">]</span>
</span></span><span class="line"><span class="cl">            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nx">event</span><span class="p">.</span><span class="nx">skipWaiting</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">self</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;fetch&#39;</span><span class="p">,</span> <span class="nx">event</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="nx">event</span><span class="p">.</span><span class="nx">respondWith</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">content</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                    <span class="p">(</span><span class="nx">cache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                        <span class="k">return</span> <span class="nx">cache</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                    <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                        <span class="kd">let</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">response</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">entries</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                                        <span class="kd">let</span> <span class="nx">date</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                        <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">pair</span> <span class="k">of</span> <span class="nx">headers</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                            <span class="k">if</span> <span class="p">(</span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="s1">&#39;date&#39;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                <span class="nx">date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                        <span class="k">if</span> <span class="p">(</span><span class="nx">date</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                            <span class="kd">let</span> <span class="nx">age</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">((</span><span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">-</span> <span class="nx">date</span><span class="p">.</span><span class="nx">getTime</span><span class="p">())</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                            <span class="kd">let</span> <span class="nx">ttl</span> <span class="o">=</span> <span class="nx">getTTL</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">.</span><span class="nx">url</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                            <span class="k">if</span> <span class="p">(</span><span class="nx">ttl</span> <span class="o">&amp;&amp;</span> <span class="nx">age</span> <span class="o">&gt;</span> <span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                <span class="k">return</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">(</span><span class="nx">resolve</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                        <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                                <span class="p">(</span><span class="nx">updatedResponse</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                                    <span class="k">if</span> <span class="p">(</span><span class="nx">updatedResponse</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                                        <span class="nx">cache</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">,</span> <span class="nx">updatedResponse</span><span class="p">.</span><span class="nx">clone</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">                                                                        <span class="nx">resolve</span><span class="p">(</span><span class="nx">updatedResponse</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                                                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                                        <span class="nx">resolve</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                                <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                                    <span class="nx">resolve</span><span class="p">(</span><span class="nx">response</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                            <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">);</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                            <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                    <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                        <span class="k">return</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl">                                            <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                    <span class="k">if</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span> <span class="o">&lt;</span> <span class="mi">400</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                        <span class="k">if</span> <span class="p">(</span><span class="o">~</span><span class="nx">SUPPORTED_METHODS</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">.</span><span class="nx">method</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">isBlacklisted</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">.</span><span class="nx">url</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                            <span class="nx">cache</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">clone</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                        <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">}</span> 
</span></span><span class="line"><span class="cl">                                                    <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                        <span class="k">return</span> <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">notFound</span><span class="p">).</span><span class="nx">then</span><span class="p">((</span><span class="nx">cache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                            <span class="k">return</span> <span class="nx">cache</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">NOT_FOUND_PAGE</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">})</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">.</span><span class="nx">then</span><span class="p">((</span><span class="nx">response</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                <span class="k">if</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                    <span class="k">return</span> <span class="nx">response</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">})</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                    <span class="k">return</span> <span class="nx">caches</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">CACHE_VERSIONS</span><span class="p">.</span><span class="nx">offline</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">.</span><span class="nx">then</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">(</span><span class="nx">offlineCache</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                                <span class="k">return</span> <span class="nx">offlineCache</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">OFFLINE_PAGE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                            <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                                        <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                                        
</span></span><span class="line"><span class="cl">                                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                            <span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">.</span><span class="k">catch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                    <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;  Error in fetch handler:&#39;</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                                    <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                            <span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Format Hugo markdown and code</title>
      <link>https://techformist.com/format-hugo-markdown-code/</link>
      <pubDate>Fri, 09 Aug 2019 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/format-hugo-markdown-code/</guid>
      <description>&lt;p&gt;Format your markdown using &lt;code&gt;prettier&lt;/code&gt; and you are off to the races.&lt;/p&gt;
&lt;p&gt;Hugo static site generator keeps everything simple. I just love the power of typing in something in markdown, and seeing the finished HTML pages and blog formatted to specs (in no time, I might add).&lt;/p&gt;
&lt;p&gt;I use VSCode for writing markdown text. This works out beautifully - I can save markdown files and prettier kicks in to format everything - the markdown within those files and the code within markdown.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Format your markdown using <code>prettier</code> and you are off to the races.</p>
<p>Hugo static site generator keeps everything simple. I just love the power of typing in something in markdown, and seeing the finished HTML pages and blog formatted to specs (in no time, I might add).</p>
<p>I use VSCode for writing markdown text. This works out beautifully - I can save markdown files and prettier kicks in to format everything - the markdown within those files and the code within markdown.</p>
<h3 id="why-use-vscode">Why use VSCode?</h3>
<p>I keep markdown and code typing similar - no brain-freeze. And, the formatting is a huge bonus as you see below.</p>
<p>What I type -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gu">###   Header 3
</span></span></span><span class="line"><span class="cl"> Hello World
</span></span><span class="line"><span class="cl">``<span class="sb">`js
</span></span></span><span class="line"><span class="cl"><span class="sb">  if (true){
</span></span></span><span class="line"><span class="cl"><span class="sb">console.log(&#34;hello world&#34;)
</span></span></span><span class="line"><span class="cl"><span class="sb">}
</span></span></span><span class="line"><span class="cl"><span class="sb">  `</span>``
</span></span></code></pre></div><p>What the content gets automatically formatted to -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl"><span class="gu">### Header 3
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Hello World
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s">```js
</span></span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&#34;hello world&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="s">```</span>
</span></span></code></pre></div><p>You may see that -</p>
<ul>
<li><code>###</code> line has extra spaces removed</li>
<li>a blank line has been added between header and content</li>
<li>another blank line added between content and the beginning of code block</li>
<li>the <code>js</code> block has been changed to -
<ul>
<li>format <code>if</code> statement as a code-block</li>
<li>semicolons at logical end</li>
</ul>
</li>
</ul>
<p>If you have been typing in markdown, you would have recognized how valuable adding blank line can be. While it is easier for prettier, markdown does not &ldquo;see&rdquo; what you meant and format the entire block of content in an altogether different way.</p>
<p>Another crucial advantage for me - I can type in code-blocks within markdown and let it automatically format. I also get to know any silly mistakes (e.g. a bracket not closed) since Prettier parser will not format the code.</p>
<h3 id="the-alternative">The Alternative</h3>
<p>If VSCode is working so well with a couple of extensions, why change that? Two reasons -</p>
<ol>
<li>I had been trying to make my workflow even more seamless</li>
<li>VSCode gobbles up a lot of memory. I want to minimise stuff I do on VSCode other than main-stream programming. Obviously all those windows are going to be open all the time, which is a big problem</li>
</ol>
<p>I wanted to retain VSCode&rsquo;s fantastic formatting support, and I can do that in just a couple of steps - thanks to Hugo.</p>
<ol>
<li>Go to your Hugo site root directory</li>
<li>If your theme does not use any kind of packages today - do <code>npm init</code>. (in other words, ignore this step if you already have <code>package.json</code> in your Hugo site root directory)</li>
<li>Install husky, lint-staged, and prettier packages -
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">  npm install husky lint-staged prettier
</span></span></code></pre></div></li>
<li>Change your <code>package.json</code> to-
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;scripts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;precommit&#34;</span><span class="p">:</span> <span class="s2">&#34;lint-staged&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;lint-staged&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;*.md&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;prettier --parser markdown --write&#34;</span><span class="p">,</span> <span class="s2">&#34;git add&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div></li>
</ol>
<p>We parse markdown file with <code>lint-staged</code> and use <code>prettier</code> to format files. <code>husky</code> enables us to prevent accidental commits before running pre-commit hook.</p>
<p>That&rsquo;s it - now you can see your files nicely formatted no matter which editor you use.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Create static sites in Vue using Gridsome</title>
      <link>https://techformist.com/create-static-sites-vue-gridsome/</link>
      <pubDate>Sun, 24 Feb 2019 15:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/create-static-sites-vue-gridsome/</guid>
      <description>&lt;p&gt;I love the simplicity, speed and awesomeness of static sites. I also happen to love Vue for its power, simplicity and its feature set that makes development that much easier.&lt;/p&gt;
&lt;p&gt;So, what will happen when Vue is combined with static sites?&lt;/p&gt;
&lt;p&gt;Awesome &lt;a href=&#34;https://gridsome.org&#34;&gt;Gridsome&lt;/a&gt; - that&amp;rsquo;s what.&lt;/p&gt;
&lt;p&gt;Gridsome describes itself as a Vue-powered site generator. Use Vue to design your site on top of Gridsome framework, and write your content in markdown, and generate complete HTML pages for your content that is complete in all respects.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I love the simplicity, speed and awesomeness of static sites. I also happen to love Vue for its power, simplicity and its feature set that makes development that much easier.</p>
<p>So, what will happen when Vue is combined with static sites?</p>
<p>Awesome <a href="https://gridsome.org">Gridsome</a> - that&rsquo;s what.</p>
<p>Gridsome describes itself as a Vue-powered site generator. Use Vue to design your site on top of Gridsome framework, and write your content in markdown, and generate complete HTML pages for your content that is complete in all respects.</p>
<p><img loading="lazy" src="/misc/gridsome-vue-static-sites.png" type="" alt=""  /></p>
<p>The awesomeness includes -</p>
<ul>
<li>Use the ever-developing theme framework of Gridsome to quickly incorporate design elements</li>
<li>Connect to other data sources like Wordpress, Contentful or any other headless CMS. The content is pulled in at the time of site generation (and you could use GraphQL!)</li>
<li>Your sites appear to be faster - navigation is similar to a SPA</li>
<li>Once generated, host your sites anywhere - they are just static files. You can leverage the speed of GitHub pages, or use GitLab, host on Netlify for free, or just use a CDN. Anything&rsquo;s possible.</li>
<li>Your sites will also work offline - thanks to the built-in PWA features</li>
</ul>
<p>I spent some quality time evaluating Gridsome for this very blog, but postponed the decision due to &rsquo;logistical&rsquo; reasons (and because I am a bit lazy). Typically though, you can use Netlify to host your sites, have your content on GitHub, and forget about everything else. Netlify will build your sites and host for free.</p>
<p><img loading="lazy" src="/misc/techformist-gridsome-sample.png" type="" alt=""  /></p>
<h3 id="alternatives">Alternatives</h3>
<p><strong>Static sites in Javascript</strong></p>
<p>There is no beating the fact that <a href="https://www.gatsbyjs.org/">Gatsby</a> is the most popular static site generator in the Javascript world - by a huge margin. The starter sites/themes, community help and plugins are really good.</p>
<p>However, when it comes to Vue, the options come down to Gridsome and Vuepress. Vuepress can be used for general purpose websites and blogs, but that is not its official purpose. Vuepress serves documentation really well. Being the official product, Vuepress may receive more love for generic sites, but that is far away in the future.</p>
<p>Nuxt and Next can do many more things than just generate static sites, but those are a couple of powerful options if you want to use them anyway. Sapper (Svelte ++ ) is also in this territory.</p>
<p>While I do acknowledge <a href="https://www.11ty.io/">11ty</a>, <a href="https://hexo.io/">Hexo</a> et. al. - the more modern frameworks like Gridsome are a class apart IMO.</p>
<p><strong>Other SSGs</strong></p>
<p>Hugo is my favourite SSG at this time - it is dead simple, Go template language is fairly easy to understand, and has quite a few themes that you can get started with.</p>
<p>Jekyll is ancient but active. I would advise against Jekyll unless you are comfortable with Ruby. Don&rsquo;t get me wrong - you can use Jekyll and its various themes (even customize them using the templating features), but sooner or later you would want to do something that is not possible within the templates themselves. The advantage with Jekyll is the ability to create Jekyll sites on GitHub and GitHub pages can compile pages without any additional build setup.</p>
<p>For a full list of other SSGs, go over to <a href="https://www.staticgen.com/">https://www.staticgen.com/</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Contact Forms in Static Sites</title>
      <link>https://techformist.com/contact-forms-in-static-sites/</link>
      <pubDate>Sun, 17 Feb 2019 15:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/contact-forms-in-static-sites/</guid>
      <description>&lt;p&gt;I don&amp;rsquo;t quite see value in &amp;lsquo;contact us&amp;rsquo; forms anymore.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No one uses it&lt;/li&gt;
&lt;li&gt;It is prone to spam&lt;/li&gt;
&lt;li&gt;No one uses it (yes, this is repeated)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, my personal opinions do not always align with client expectations. So it follows that I create these forms on a static site with resigned indignation.&lt;/p&gt;
&lt;p&gt;Contact form is not quite a native feature of static sites. However, there are more than few solutions to this problem.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I don&rsquo;t quite see value in &lsquo;contact us&rsquo; forms anymore.</p>
<ul>
<li>No one uses it</li>
<li>It is prone to spam</li>
<li>No one uses it (yes, this is repeated)</li>
</ul>
<p>However, my personal opinions do not always align with client expectations. So it follows that I create these forms on a static site with resigned indignation.</p>
<p>Contact form is not quite a native feature of static sites. However, there are more than few solutions to this problem.</p>
<h5 id="use-contact-form-from-a-third-party-site">Use contact form from a third party site</h5>
<p>Use the form provided by the email marketing provider, or use a service like <a href="https://formspree.io/">Formspree</a>. You just need to use some Javascript or use a simple URL to embed the form in the site.</p>
<p>For example, Formspree just requires you to include following content -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">form</span> <span class="na">action</span><span class="o">=</span><span class="s">&#34;https://formspree.io/email@domain.tld&#34;</span> <span class="na">method</span><span class="o">=</span><span class="s">&#34;POST&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;name&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;email&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;_replyto&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Send&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>User-entered data is maintained and processed by the service provider. You as a developer do not have anything additional to do here.</p>
<p>On the flip side, the features provided by the form provider may not quite match client expectations. The low-tier plans or free plans may be a tad too limited for the client tastes (but without the option to bump up the tiers).</p>
<h5 id="link-to-a-third-party-existing-site-from-the-client">Link to a third party existing site from the client</h5>
<p>Use an external site that is already owned by client organization in order to provide the contact form. This has the added advantage of centralizing contact information from multiple sources, and forcing the same tried-and-tested procedure to process contact requests.</p>
<p>Or, build (/ consume) a small API in existing enterprise applications (like Zoho) to feed in the contact information.</p>
<p>These third party sites, however, are not always an option that is readily available (or within budget).</p>
<h5 id="use-netlify-forms-if-you-are-hosted-on-netlify">Use Netlify Forms if you are hosted on Netlify</h5>
<p>The simplest solution of them all is to use Netlify forms. All you need to do is include the <code>netlify</code> tag in the forms.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">form</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;contact&#34;</span> <span class="na">method</span><span class="o">=</span><span class="s">&#34;POST&#34;</span> <span class="na">data-netlify</span><span class="o">=</span><span class="s">&#34;true&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">label</span><span class="p">&gt;</span>Your Email: <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;email&#34;</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;email&#34;</span> <span class="p">/&gt;&lt;/</span><span class="nt">label</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Any user entered data will be redirected to Netlify and the data is available to internal users through the Netlify admin function. You also have the option to send this data to external systems without fuss if you are on a non-free tier.</p>
<h5 id="but-contact-forms">But.. contact forms?</h5>
<p>I often see potential customers calling up the customer-facing team rather than use contact forms in the case of smaller industries in my clientele. However, I need to do a better test one of these days rather than relying on my intellect that is far too superior for my own good.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>CMS, Site Builders and Static Sites</title>
      <link>https://techformist.com/cms-site-builders-and-static-sites/</link>
      <pubDate>Sun, 10 Feb 2019 15:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/cms-site-builders-and-static-sites/</guid>
      <description>&lt;p&gt;Does the term &amp;lsquo;CMS&amp;rsquo; mean anything anymore? And, why a hybrid static site solution is the only way out.&lt;/p&gt;
&lt;h5 id=&#34;where-we-stand-today&#34;&gt;Where we stand today?&lt;/h5&gt;
&lt;p&gt;Wordpress really brought web sites to the masses. Instead of writing obscure code using HTML / Javascript, using Blogspot, or using third party site builders, Wordpress and its ecosystem allowed all humans with basic computer skills to whip up a site within no time.&lt;/p&gt;
&lt;p&gt;Wordpress is a content management system (&amp;ldquo;CMS&amp;rdquo;), and a good CMS at that.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Does the term &lsquo;CMS&rsquo; mean anything anymore? And, why a hybrid static site solution is the only way out.</p>
<h5 id="where-we-stand-today">Where we stand today?</h5>
<p>Wordpress really brought web sites to the masses. Instead of writing obscure code using HTML / Javascript, using Blogspot, or using third party site builders, Wordpress and its ecosystem allowed all humans with basic computer skills to whip up a site within no time.</p>
<p>Wordpress is a content management system (&ldquo;CMS&rdquo;), and a good CMS at that.</p>
<p>Wordpress has improved over time, and it can do much much more than what it could do even 2 years back. But it is still old school.</p>
<p>The other CMS&rsquo;s like Drupal or Joomla did not make it to the public consciousness. They solved problems for a different type of audience - and their efficacy at doing that in a rapidly changing world is called into question.</p>
<p>Meanwhile, there are site builders like Squarespace, Wix et. al. that started as &ldquo;website builders&rdquo;, but have been attaching CMS to their names. Nothing wrong, technically. They help users to manage content, may not be at the same level as their revered ancestors - and that&rsquo;s ok.</p>
<p>There&rsquo;s a new breed of headless CMS&rsquo;es. These just refer to software systems that may or may not have UI of their own. But they do provide an efficient way to manage content. You can consume and present that content using your favourite frontend tool.</p>
<p>And, then - there are static sites. Sites that cut off the middleman in preparing content for the audience, instead (almost) everything is pre-compiled and ready-to-serve. But at the same time, do not take on the responsibility of role-based access or dynamic content.</p>
<h5 id="wheres-the-problem">Where&rsquo;s the problem?</h5>
<p>So, if everyone and everything has its place in the universe, how is anything a problem with this land?</p>
<p>The situation in CMS today is diverse -</p>
<ol>
<li>Proprietary tech that can lock you down - this applies not only to Wix but also to digital publishing platforms like Medium</li>
<li>Surprising range of functions. Any application with a semblance of a role and a way of presenting data to an audience calls itself a CMS</li>
<li>Old school tech that relies on slow DB operations and unwarranted complexities, hybrid approaches with no standards and newer way of doing things that most likely do not stand the test of time</li>
</ol>
<p>I feel individuals and even organizations do not carefully evaluate the path they want to take here. The main issue is not the CMS itself, but the definition of CMS.</p>
<p>CMS&rsquo;s traditionally include -</p>
<ul>
<li>A way to create and manage digital content incl. text, images and videos</li>
<li>A collaboration system where multiple people can come together to create artefacts</li>
</ul>
<p>Today, you can create sites at a click of a button and have advanced functionality enabled in a couple of more clicks. These sites may manage plenty of content without even calling itself a CMS accomplish many many more things that a traditional CMS may not do.</p>
<p>Many of the modern CMS&rsquo;s may also mix content and presentation at any time before the actual presentation. Think static sites. CMS may also not have a presentation layer at all!</p>
<ul>
<li>StrapiJS (a headless CMS) is a back-end application for any and all data. It happens to have a good ACL too</li>
<li>Static sites and hybrid sites pre-cook content + presentation</li>
</ul>
<blockquote>
<p>I believe that CMS is dead, and the new breed should be called something else.</p>
</blockquote>
<p>CoMaS, may be - that is easier to pronounce. Or just may be calling them for what they are - site builders, back-end applications (BaaS / BPaaS, anyone?), static sites and the like.</p>
<p>Although this very much looks like some two people&rsquo;s effort to rebrand &lsquo;customer relationship management&rsquo; into &lsquo;customer experience&rsquo; - this is equally challenging times for all technologies that want to get contained in a box.</p>
<h5 id="where-are-we-headed">Where are we headed?</h5>
<p>A fairly quick conclusion to the pointless rant - the future is &lsquo;hybrid&rsquo;. Combine static site generation with the power of dynamic content to produce hybrid solutions that handle anything thrown at them.</p>
<ol>
<li>Use static site generation technologies for static content. Prep content so that presentation can be faster</li>
<li>Use APIs to provide options to use any front-end tools</li>
<li>Fall back on DBs (relational or otherwise) to enable dynamic behaviour - may it be role-based access, collaboration tools or for digital publishing</li>
</ol>
<p>I would love to believe Wordpress will evolve to do all this and much more. Many plugins already provide a quick way to setup static content, and all it needs is to be a couple of notches higher.</p>
<p>But, I am betting big on an altogether new player to take the lead on this one. The question is whether any of the existing players take that role to create an open platform by foregoing the short-term monetization option.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Web Inspector to design static sites</title>
      <link>https://techformist.com/web-inspector-to-design-static-sites/</link>
      <pubDate>Wed, 06 Feb 2019 15:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/web-inspector-to-design-static-sites/</guid>
      <description>&lt;p&gt;Chrome and Firefox web inspectors are my new best friends in my quest to develop static sites. I never took the time to appreciate the complete power of web inspection - until I actually started changing the design of this very site.&lt;/p&gt;
&lt;p&gt;I have been redesigning &lt;a href=&#34;https://techformist.com&#34;&gt;techformist.com&lt;/a&gt; website on Hugo. The plan is to migrate from Jekyll and design a simpler site that can easily showcase what I have to offer (ahem..).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Chrome and Firefox web inspectors are my new best friends in my quest to develop static sites. I never took the time to appreciate the complete power of web inspection - until I actually started changing the design of this very site.</p>
<p>I have been redesigning <a href="https://techformist.com">techformist.com</a> website on Hugo. The plan is to migrate from Jekyll and design a simpler site that can easily showcase what I have to offer (ahem..).</p>
<p>While there are excellent ways to develop Go templates on my own, I always appreciate the opportunity to stand on the shoulders of giants. I selected the <a href="https://minimo.netlify.com/">Minimo theme</a> for the purpose and started customizing CSS alongside a few changes in the layouts and templates.</p>
<p>It was then and only then I could completely and deeply commit myself to the inspectors.</p>
<p>You see - all of my &lsquo;professional&rsquo; web development life has been spent using UI standards and libraries like Materialize, Bulma and Bootstrap. These offer a million ways of personalizing stuff but, at the same time, stay abstract from targeting CSS changes for specific, individual elements / ids / classes.</p>
<p>This changed when I started personalizing fonts, colours, borders et. al. on a static site theme like Minimo that did not use these standards. I had to start identifying the individual tags, ids and elements in the CSS path so that they can be over-ridden in <code>custom.css</code> file provided by the theme.</p>
<p>While this seemed trivial from my experience with other themes, Minimo had a slightly different approach and had an arguably better hierarchical structure in CSS. (Actually, the theme used SCSS that I did not bother to override, I chose the easier path.)</p>
<p>After about 10 minutes of wrangling with elements, I was seriously contemplating on switching to another generator altogether. It was then I started using the web inspector in the way it was supposed to be used.</p>
<p>Click, find CSS path and use the path in <code>custom.css</code> to override the style. This was so efficient and easy.</p>
<p>In a span of 4-6 hours over 2 days I had done multiple iterations of the site including a few template/layout changes. What you see may be that, or may be a few more changes. The point is - such changes to styles on a SSG is much much more simplified if you use web inspector.</p>
<p>But wait - that is not my final advice. If I would redo anything, I would probably use a starter theme based on Bulma or Tailwind and start customizing from that baseline. I believe that will be an easier, more intuitive customization option than the &ldquo;start from scratch&rdquo; approach.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Copy/paste Datatable Issues in Hugo</title>
      <link>https://techformist.com/copy-paste-datatable-issues-in-hugo/</link>
      <pubDate>Fri, 26 Oct 2018 15:38:00 +0000</pubDate>
      
      <guid>https://techformist.com/copy-paste-datatable-issues-in-hugo/</guid>
      <description>&lt;p&gt;It is interesting how the minor things eat away a lot of your time. Especially if you happen to be like me, one of the greater idiots on a planet full of idiots.&lt;/p&gt;
&lt;p&gt;One of the days, I had to create website really fast to demonstrate to a potential customer. I abandoned my dear old friend Jekyll since - well, I had to create something in Hugo.&lt;/p&gt;
&lt;p&gt;There was a requirement to show a data list (phone numbers and some related information) on one of the pages.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>It is interesting how the minor things eat away a lot of your time. Especially if you happen to be like me, one of the greater idiots on a planet full of idiots.</p>
<p>One of the days, I had to create website really fast to demonstrate to a potential customer. I abandoned my dear old friend Jekyll since - well, I had to create something in Hugo.</p>
<p>There was a requirement to show a data list (phone numbers and some related information) on one of the pages.</p>
<pre tabindex="0"><code>|Phone | Active|
|+91 1029292122 | Y|
|+91 1298329929 | Y|
|+91 1192389292 | Y|
</code></pre><p>Easy enough.</p>
<p>But, this data had to be changed by the end user - who is not super computer-savvy) and does not want to mess around with templates or <code>md</code> files.</p>
<p>There is Hugo feature called <a href="https://gohugo.io/templates/data-templates/#data-driven-content">Data Driven Content</a> to help in those situations.</p>
<p>So this..</p>
<h4 id="step-1">Step 1:</h4>
<p>Create CSV file in the static (static/csv) under my root folder.</p>
<h4 id="step-2">Step 2:</h4>
<p>Create a new partial in <code>Layouts</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;basic-content&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;container&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">$</span><span class="p">(</span><span class="s2">&#34;#csvnum&#34;</span><span class="p">).</span><span class="nx">dataTable</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">table</span>
</span></span><span class="line"><span class="cl">      <span class="na">id</span><span class="o">=</span><span class="s">&#34;csvnum&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">class</span><span class="o">=</span><span class="s">&#34;table table-striped table-bordered&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">style</span><span class="o">=</span><span class="s">&#34;width:100%&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>Phone<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>Active<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{ $url := &#34;static/csv/phone_active.csv&#34; }} {{ $sep := &#34;,&#34; }} {{ range
</span></span><span class="line"><span class="cl">        $i, $r := getCSV $sep $url }}
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>{{ index $r 0 }}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">          <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>{{ index $r 1 }}<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{ end }}
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>So far so good. Except, the outcome isn&rsquo;t anything but what I expect.</p>
<p>I get following errors depending on whether I refresh the browser during an even second or an odd second.</p>
<pre tabindex="0"><code>TypeError: c is undefined
</code></pre><p>OR</p>
<pre tabindex="0"><code>TypeError: col is undefined
</code></pre><p>I don&rsquo;t claim to be an expert on JS, but did a fair bit of debugging here. My interim thoughts were focused on investigating how <code>$(document).ready</code> was called even though the data was not ready yet. I assumed this was the sole reason since the static table was getting rendered but the data from file wasn&rsquo;t. What other reason could there be?</p>
<p>It turns out there are many valid reasons for the problem. And, I should not blame the collective wisdom of Javascript at every second error.</p>
<p>Excel and some formatting issues had introduced a third phantom column in the CSV. For good or for worse (mostly the latter), this did not show up in Excel, or in Notepad.</p>
<p>Datatable was all weird since <code>&lt;th&gt;</code> defines two columns while <code>&lt;td&gt;</code> has three.</p>
<p>The debugging of this problem should have ideally taken less than five minutes, and there I was exploring why the data table would not work after two hours of reading email, debugging stuff, checking Feedly, and so forth.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Create Beautiful, Performant Sites [Free eBook]</title>
      <link>https://techformist.com/create-beautiful-performant-sites-free-ebook/</link>
      <pubDate>Tue, 23 Oct 2018 09:59:00 +0000</pubDate>
      
      <guid>https://techformist.com/create-beautiful-performant-sites-free-ebook/</guid>
      <description>&lt;p&gt;I had been exploring Jekyll for quite sometime. I simply followed the below traditional, developer like approach -&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;download Ruby&lt;/li&gt;
&lt;li&gt;download Jekyll&lt;/li&gt;
&lt;li&gt;play around with platform capabilities - focus on Liquid&lt;/li&gt;
&lt;li&gt;see how themes are created&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, I realised mid-way that select themes offer a good way for anyone to get started.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just copy themes to your own repository&lt;/li&gt;
&lt;li&gt;Edit content&lt;/li&gt;
&lt;li&gt;Go-live on github.io&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This information is available to anyone who is remotely interested, but the conversation on such sites were not as prevalent as they should be.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I had been exploring Jekyll for quite sometime. I simply followed the below traditional, developer like approach -</p>
<ul>
<li>download Ruby</li>
<li>download Jekyll</li>
<li>play around with platform capabilities - focus on Liquid</li>
<li>see how themes are created</li>
</ul>
<p>However, I realised mid-way that select themes offer a good way for anyone to get started.</p>
<ul>
<li>Just copy themes to your own repository</li>
<li>Edit content</li>
<li>Go-live on github.io</li>
</ul>
<p>This information is available to anyone who is remotely interested, but the conversation on such sites were not as prevalent as they should be.</p>
<p>So, I created a free book to introduce Jekyll platform to non-programmers and beginners. The book &ldquo;Level-up your Websites using Jekyll&rdquo; will take you through the process of creating a website quickly (and for free) by using themes.</p>
<p>Go through the <a href="https://github.com/prashanth1k/levelup-your-websites-using-jekyll">book on GitHub</a>.</p>
<p>Upvote on <a href="https://www.producthunt.com/posts/level-up-your-websites-using-jekyll">ProductHunt</a> if you find it interesting enough!</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
