<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[aboutDavid's Blog]]></title><description><![CDATA[Hi, I'm David!]]></description><link>https://blog.aboutdavid.me</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 11:26:49 GMT</lastBuildDate><atom:link href="https://blog.aboutdavid.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to make a blog with 11ty and GhostCMS]]></title><description><![CDATA[This is a pretty easy task considering we are not using the file system, but using JSON from an external source.
Install the packages that we need
npm install @tryghost/content-api @11ty/eleventy --save

That's it. 
Getting the data from Ghost
In _da...]]></description><link>https://blog.aboutdavid.me/how-to-make-a-blog-with-11ty-and-ghostcms</link><guid isPermaLink="true">https://blog.aboutdavid.me/how-to-make-a-blog-with-11ty-and-ghostcms</guid><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[blog]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Tue, 10 Nov 2020 18:40:00 GMT</pubDate><content:encoded><![CDATA[<p>This is a pretty easy task considering we are not using the file system, but using JSON from an external source.</p>
<h3 id="install-the-packages-that-we-need">Install the packages that we need</h3>
<pre><code class="lang-sh">npm install @tryghost/content-api @11ty/eleventy --save
</code></pre>
<p>That's it. </p>
<h3 id="getting-the-data-from-ghost">Getting the data from Ghost</h3>
<p>In <code>_data/posts.js</code>, we can make the following file:</p>
<p>Basically, it:</p>
<ul>
<li>Require's the module</li>
<li>Setup the API to get data (setting the keys, etc)</li>
<li>Exports the posts using module.exports.</li>
</ul>
<p>For this example, we will use the demo ghost instance located at demo.ghost.io.</p>
<h3 id="setting-up-the-layout">Setting up the layout</h3>
<p>In a file called <code>_includes/base.html</code>, insert the following:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My Awesome Blog!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding-left:32px;padding-right:32px;"</span>&gt;</span>
    {{ content | safe }}
    <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Basically, this creates a basic HTML document, Changes the title to My Awesome Blog!, and inserts the content.</p>
<h3 id="setting-up-the-list-of-posts">Setting up the list of posts</h3>
<p>Make a new file called <code>index.html</code>.</p>
<pre><code class="lang-html">---
layout: base.html
---
<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>
  My Awesome Blog
<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  {% for post in posts %}
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/posts/{{ post.slug }}"</span>&gt;</span>{{ post.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  {% endfor %}
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<p>This basically says:
"Use the layout base.html in the folder _includes, Then, for every post from GhostCMS, make a new unordered list item with the link /post/{{ post.slug }} and the Title {{ post.title }}."
Run eleventy and visit your site. It should look something like this:</p>
<p>We have a blog! But, If you click a link, it shows a 404 error. Lets fix that. Make a new file called <code>posts.html</code> and add the following:</p>
<pre><code class="lang-html">---
pagination:
  data: posts
  alias: post
  size: 1
permalink: posts/{{ post.slug }}/
layout: base.html
---

<span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>
  {{ post.title }}
<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"content"</span>&gt;</span>
  {{ post.html | safe }}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>This basically uses 11ty's pagination feature and creates a new page for every post, then inserts the data into the page. Run <code>eleventy</code> again.</p>
<p>Great, we are finished, right? Nope. The webpage just looks, ugly. We can fix this with 1 line of CSS using <a target="_blank" href="https://watercss.kognise.dev/">water.css</a>. Just insert the following line into <code>_includes/base.html</code> in the <code>&lt;head&gt;</code> tag:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css"</span>&gt;</span>
</code></pre>
<p>Run <code>eleventy</code> for the last. The webpage looks 100% better now! Now we have a blog. Thanks for reading!</p>
<p>Note: Every time you make a new post/update it, you will have to update it using the <code>eleventy</code> command.</p>
]]></content:encoded></item><item><title><![CDATA[I made my own blog using 11ty, 11ty base blog, and Bulma.]]></title><description><![CDATA[In one of my mirrored DEV posts, you may have seen that it was originally published on notebook.aboutdavid.me

That's my new blog that I have started. It's going to be more of a personal blog because my Hashnode blog is more developer focused.
Requir...]]></description><link>https://blog.aboutdavid.me/i-made-my-own-blog-using-11ty-11ty-base-blog-and-bulma</link><guid isPermaLink="true">https://blog.aboutdavid.me/i-made-my-own-blog-using-11ty-11ty-base-blog-and-bulma</guid><category><![CDATA[2Articles1Week]]></category><category><![CDATA[blog]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Fri, 06 Nov 2020 20:42:38 GMT</pubDate><content:encoded><![CDATA[<p>In one of my mirrored DEV posts, you may have seen that it was originally published on notebook.aboutdavid.me</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604686346501/0NlMFrTva.png" alt="EMTsU20YIS.png" /></p>
<p>That's my new blog that I have started. It's going to be more of a personal blog because my <a target="_blank" href="https://blog.aboutdavid.me">Hashnode blog</a> is more developer focused.</p>
<h3 id="requirements">Requirements</h3>
<ul>
<li>It is supposed to be simple, yet elegant</li>
<li>As less clicks as possible</li>
<li>No "sell your data" analytics.</li>
<li>Be able to easily setup (Like those easy "Deploy to Heroku" buttons)</li>
<li>Make it easy to write posts</li>
<li>Gzip and Brotli compression</li>
<li>Caching (ability to make website load faster/save bandwith)/Ability to work offline</li>
<li>Custom Emojis for cross-browser/device platform compatibility</li>
<li>Open Graph Images</li>
</ul>
<h3 id="meeting-those-requirements">Meeting those requirements</h3>
<ul>
<li>The simple, yet elegant part was easily solved by using the <a target="_blank" href="https://bulma.io">Bulma CSS framework</a> with <a target="_blank" href="https://webpack.js.org">Webpack</a></li>
<li>The "less clicks" problem was just solved by putting all of the posts on one page. Just one click to see the content that you want!
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1604693796951/VfWlDDDYK.png" alt="brave_5Lm7stejkD.png" /></li>
<li>The analytics problem was by using Simple Analytics. I've decided to make my analytics public so you can find them <a target="_blank" href="https://simpleanalytics.com/notebook.aboutdavid.me">here!</a></li>
<li>The easy to set up problem was solved by having a <code>_data/metadata.json</code> where all of the config goes so I can easily modify it at any time</li>
<li>I made it easier to write posts by just using Markdown. That's seriously it.</li>
<li>Gzip and Brotli compression is actually very easy when you use <a target="_blank" href="https://npmjs.com/package/http-server">http-server</a>. It is also faster to start then using 11ty's built in <code>--serve</code> option.</li>
<li>Caching/Ability to work online was easily done by using a Service Worker.</li>
<li>Custom Emojis were solved by using Twemoji. You can easily set that up <a target="_blank" href="https://gist.github.com/aboutDavid/130eaa4a61d87eff9ff47b30ad08bf00">here</a></li>
<li>Open Graph Images can be made using <a target="_blank" href="https://github.com/vercel/og-image">vercel/og-image</a> with a few changes. I made a fork of the repo and made those changes <a target="_blank" href="https://github.com/aboutDavid/notebook-og-image-cards">here.</a></li>
</ul>
<h3 id="screenshots">Screenshots:</h3>
<p><img src="https://file.coffee/u/oSCvuVLJnu.png" alt />
<img src="https://file.coffee/u/vnGWqtnf3B.png" alt />
<img src="https://file.coffee/u/UmLBSBrt8V.png" alt />
<img src="https://file.coffee/u/sXekWmUUU6.png" alt /></p>
<h3 id="what-i-have-learned">What I have learned:</h3>
<ul>
<li>For bigger projects that use webpack, you might want to use SASS as it is very easy to learn and include</li>
<li>Webpack can bundle so many different file types! Images, JavaScript CSS, SCSS, SASS, Handlebars, cjs, etc.</li>
<li>I learned more about Nunjucks because of 11ty.</li>
<li>I learned more about 11ty and how it works and how to use plugins.</li>
</ul>
<p>You can see a demo of it <a target="_blank" href="https://notebook.aboutdavid.me">here</a></p>
<p>Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[Cheat sheet for webpack's config rules]]></title><description><![CDATA[Webpack's config rules may seem complicated, but it really isn't! This is a simple "cheatsheet" that you can use for webpack's config. 
Here is where you place the rules:
 module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resol...]]></description><link>https://blog.aboutdavid.me/cheat-sheet-for-webpacks-config-rules</link><guid isPermaLink="true">https://blog.aboutdavid.me/cheat-sheet-for-webpacks-config-rules</guid><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Thu, 05 Nov 2020 15:37:33 GMT</pubDate><content:encoded><![CDATA[<p>Webpack's config rules may seem complicated, but it really isn't! This is a simple "cheatsheet" that you can use for webpack's config. </p>
<p>Here is where you place the rules:</p>
<pre><code class="lang-diff"> module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/bundle.js",
  },
  mode: "development",
  module: {
<span class="hljs-addition">+ rules: [],</span>
  },
};
</code></pre>
<p>Your config does <strong>not</strong> have to look like the one above, I was just showing you where the rules go (in the module.rules array) and how it looks</p>
<h3 id="javascript-and-json">JavaScript and JSON</h3>
<p>Nothing is really needed for these two languages as webpack natively supports them</p>
<h3 id="cssscss">CSS/SCSS</h3>
<p>You do need a few packages to import CSS and/or SCSS into webpack, but it works like a charm.</p>
<p>Install the packages needed with this command:</p>
<pre><code class="lang-sh">npm install postcss-loader style-loader sass-loader  css-loader --save
</code></pre>
<p>Then, insert the following rule in <code>webpack.config.js</code> under module -&gt; rules:</p>
<pre><code class="lang-js">{
    <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(scss|css)$/</span>,
    use: [<span class="hljs-string">'style-loader'</span>, <span class="hljs-string">'css-loader'</span>, <span class="hljs-string">'postcss-loader'</span>, <span class="hljs-string">'sass-loader'</span>],
},
</code></pre>
<h3 id="images">Images</h3>
<p>Yes, you can use images in webpack. You will need to use the <a target="_blank" href="https://webpack.js.org/guides/asset-modules/">Assets modules rule</a> functions.</p>
<p>Insert the following rule in <code>webpack.config.js</code> under module -&gt; rules:</p>
<pre><code class="lang-js">{
    <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(?:ico|gif|png|jpg|jpeg)$/i</span>,
    type: <span class="hljs-string">'asset/resource'</span>
},
</code></pre>
<h3 id="fonts-and-svg-files">Fonts and SVG files</h3>
<p>For this one, you need to use something inline assets</p>
<p>Insert the following rule in <code>webpack.config.js</code> under module -&gt; rules:</p>
<pre><code class="lang-js">{
    <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(woff(2)?|eot|ttf|otf|svg|)$/</span>,
    type: <span class="hljs-string">'asset/inline'</span>,
},
</code></pre>
<h3 id="babel">Babel</h3>
<p>Babel is a compiler for the next generation JavaScript, today. You can basically use newer JavaScript in older browsers like Internet Explorer.</p>
<p>Install the packages needed with this command:</p>
<pre><code class="lang-sh">npm i @babel/core @babel/preset-env babel-loader @babel/plugin-proposal-class-properties --save
</code></pre>
<p>Then, insert the following rule in <code>webpack.config.js</code> under module -&gt; rules:</p>
<pre><code class="lang-js">{
    <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
    exclude: <span class="hljs-regexp">/node_modules/</span>,
    use: [<span class="hljs-string">'babel-loader'</span>],
},
</code></pre>
<p>I actually made this cheat sheet for myself, but I decided to share it with everyone! Enjoy!</p>
]]></content:encoded></item><item><title><![CDATA[Using Glitch to develop apps with their real time IDE editor.]]></title><description><![CDATA[Now what is Glitch? Glitch is a Real-time IDE which saves as soon as you type. Now why Glitch over any other online IDE? Well, it's instant. Like really instant. As soon as you say, type the letter "h" it saves instantly.
Great, right? Another cool t...]]></description><link>https://blog.aboutdavid.me/using-glitch-to-develop-apps-with-their-real-time-ide-editor</link><guid isPermaLink="true">https://blog.aboutdavid.me/using-glitch-to-develop-apps-with-their-real-time-ide-editor</guid><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Tue, 27 Oct 2020 03:22:23 GMT</pubDate><content:encoded><![CDATA[<p>Now what is Glitch? Glitch is a Real-time IDE which saves as soon as you type. Now why Glitch over any other online IDE? Well, it's instant. Like really instant. As soon as you say, type the letter "h" it saves instantly.</p>
<p>Great, right? Another cool thing is you can make demos for you app and anyone can remix them and share them. For example, you can click <a target="_blank" href="https://glitch.com/edit/#!/remix/hello-express">here</a> to get a express server running on your own custom domain. No account, no anything. Try it out!</p>
<p>Lets get into the developer stuff. We first need to know what we can use:</p>
<pre><code class="lang-md"><span class="hljs-bullet">-</span> CSS (Cascading Style Sheets)
<span class="hljs-bullet">-</span> HTML(Hyper Text Markup Language)
<span class="hljs-bullet">-</span> Ember.JS
<span class="hljs-bullet">-</span> Ruby
<span class="hljs-bullet">-</span> Ruby on Rails
<span class="hljs-bullet">-</span> Python
<span class="hljs-bullet">-</span> pip
<span class="hljs-bullet">-</span> Java
<span class="hljs-bullet">-</span> Rust
<span class="hljs-bullet">-</span> C
<span class="hljs-bullet">-</span> C++
<span class="hljs-bullet">-</span> .NET
<span class="hljs-bullet">-</span> Swift
<span class="hljs-bullet">-</span> ClojureScript
<span class="hljs-bullet">-</span> PHP
<span class="hljs-bullet">-</span> Perl
<span class="hljs-bullet">-</span> Haskell
<span class="hljs-bullet">-</span> Elixir
<span class="hljs-bullet">-</span> CPAN
<span class="hljs-bullet">-</span> Racket
<span class="hljs-bullet">-</span> JavaScript
<span class="hljs-bullet">-</span> BuckleScript
<span class="hljs-bullet">-</span> Lua
<span class="hljs-bullet">-</span> Xen Text
<span class="hljs-bullet">-</span> CoffeeScript
<span class="hljs-bullet">-</span> EJS
<span class="hljs-bullet">-</span> PUG
<span class="hljs-bullet">-</span> Jade
<span class="hljs-bullet">-</span> Deno
<span class="hljs-bullet">-</span> Lisp
<span class="hljs-bullet">-</span> Node.JS
<span class="hljs-bullet">-</span> Bash
<span class="hljs-bullet">-</span> Discord.PY
<span class="hljs-bullet">-</span> Discord.JS
<span class="hljs-bullet">-</span> Node Package Manager (NPM) (Inaccessible in the app terminal)
<span class="hljs-bullet">-</span> Shell
<span class="hljs-bullet">-</span> React.JS
<span class="hljs-bullet">-</span> Draft.JS
<span class="hljs-bullet">-</span> C# (C Sharp)
<span class="hljs-bullet">-</span> TypeScript
<span class="hljs-bullet">-</span> Vue.JS
<span class="hljs-bullet">-</span> Gem
<span class="hljs-bullet">-</span> Yarn
<span class="hljs-bullet">-</span> Poetry
<span class="hljs-bullet">-</span> Pipenv
<span class="hljs-bullet">-</span> Nuxt.JS
<span class="hljs-bullet">-</span> Svelte.JS
<span class="hljs-bullet">-</span> Next.JS
<span class="hljs-bullet">-</span> SQL
<span class="hljs-bullet">-</span> Django (needs to be installed with pip3 install Django
<span class="hljs-bullet">-</span> Flask
<span class="hljs-bullet">-</span> Bottle
<span class="hljs-bullet">-</span> Pysimplegui
<span class="hljs-bullet">-</span> Web2py
<span class="hljs-bullet">-</span> TurboGears
<span class="hljs-bullet">-</span> uWSGI
<span class="hljs-bullet">-</span> Twisted
<span class="hljs-bullet">-</span> Tornado
<span class="hljs-bullet">-</span> 11ty
<span class="hljs-bullet">-</span> Binary
</code></pre>
<p>You can find that same list (and even more) <a target="_blank" href="https://support.glitch.com/t/list-of-supported-languages-frameworks-and-package-managers/28279">here!</a>. Now we can start developing. Write some basic code or make a major project.</p>
<h3 id="what-to-do-when-you-are-done">What to do when you are done:</h3>
<ol>
<li>Share your work in <a target="_blank" href="https://support.glitch.com/c/the-gallery/6">the gallery</a>. The forum members like to see awesome projects</li>
<li>Export to GitHub. This is actually pretty easy. There is a button called "Export to GitHub" under <code>Tools-&gt;Import and Export</code>. All you have to do is sign in with GitHub. You can also use the console (Tools-&gt;Console) and use <code>git push https://github.com/user/repo main</code> which might work better.</li>
<li>Share on twitter: Share your work on Twitter! You can also mention <a target="_blank" href="https://twitter.com/glitch">@glitch</a> on twitter and they might see it too!</li>
</ol>
<h3 id="fun-facts">Fun Facts:</h3>
<ul>
<li>Did you know that every Glitch project is it's own Git repo? Yep, all you have to do to get the Git url is under Tools -&gt; Import and Export -&gt; Your project's Git URL. There you can click "copy" and get your Git repo URL!</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Customizing my hashnode blog using the custom CSS feature]]></title><description><![CDATA[Today I decided to customize my hashnode blog using hashnode's custom CSS setting. Now if you know the basics of CSS, you can easily customize your own blog. In this article, I will show you how I customized my blog.
Note: Currently, you have to be a...]]></description><link>https://blog.aboutdavid.me/customizing-my-hashnode-blog-using-the-custom-css-feature</link><guid isPermaLink="true">https://blog.aboutdavid.me/customizing-my-hashnode-blog-using-the-custom-css-feature</guid><category><![CDATA[2Articles1Week]]></category><category><![CDATA[CSS]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Sun, 25 Oct 2020 21:04:27 GMT</pubDate><content:encoded><![CDATA[<p>Today I decided to customize my hashnode blog using hashnode's custom CSS setting. Now if you know the basics of CSS, you can easily customize your own blog. In this article, I will show you how I customized my blog.</p>
<p><strong>Note:</strong> Currently, you have to be an ambassador to use the custom CSS feature.</p>
<p>You can access the custom CSS feature in Dashboard -&gt; Appearance -&gt; Add Custom CSS</p>
<h3 id="custom-header-colors-all-sections">Custom header colors (All sections)</h3>
<p>I chose a light and a dark theme color so they match the light and dark themes of hashnode.</p>
<p>In this case, I chose a light green for light mode and a darker green for dark mode.</p>
<p>This was done by using the "background-color" property.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.blog-header</span> {
<span class="hljs-comment">/* Light mode */</span>
    <span class="hljs-attribute">background-color</span>:<span class="hljs-number">#00FA9A</span>;
}
<span class="hljs-selector-class">.mode-dark</span> <span class="hljs-selector-class">.blog-header</span> {
<span class="hljs-comment">/* Dark mode */</span>
    <span class="hljs-attribute">background-color</span>:<span class="hljs-number">#66CDAA</span>;
}
</code></pre>
<p>Before: Dark mode:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603598354903/qaqbAFPRC.png?auto=compress" alt />
Before: Light mode:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603599576806/Ep2z4r9rp.png?auto=compress" alt /></p>
<p>After: Dark mode
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603599704494/35WOE2mid.png?auto=compress" alt /></p>
<p>After: Light mode
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603599684047/f5yQKP59Y.png?auto=compress" alt /></p>
<h3 id="custom-headersunderlines-article-section">Custom headers/underlines (Article section)</h3>
<pre><code class="lang-css"><span class="hljs-selector-tag">h2</span>,<span class="hljs-selector-tag">h3</span>,<span class="hljs-selector-tag">h4</span>,<span class="hljs-selector-tag">h5</span>,<span class="hljs-selector-tag">h6</span>,<span class="hljs-selector-tag">b</span>,<span class="hljs-selector-tag">u</span> {
       <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(rgba(<span class="hljs-number">255</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>) <span class="hljs-number">60%</span>,<span class="hljs-number">#66cdaa</span> <span class="hljs-number">40%</span>);
}
</code></pre>
<p>Yay! But something isn't right:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603641782373/GnFLw2Z27.png" alt="56lHS2gitR.png" /></p>
<p>The line is too wide, so lets fix by using <code>display: inline-block;</code></p>
<pre><code class="lang-diff">h2,h3,h4,h5,h6,b,u {
    background: linear-gradient(rgba(255,0,0,0) 60%,#66cdaa 40%);
<span class="hljs-addition">+  display: inline-block;</span>
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603645841353/9hmhIij5J.png" alt="image.png" /></p>
<h3 id="sticky-headers-article-section">Sticky headers (Article section)</h3>
<p>Not really that hard as <code>position: sticky;</code> property. I mainly added this feature because if you are reading a long article, you have to scroll all the way back up to toggle the theme/search for other articles.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.blog-header</span> {
    <span class="hljs-attribute">position</span>: -webkit-sticky; <span class="hljs-comment">/* Safari support */</span>
    <span class="hljs-attribute">position</span>: sticky;
    <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
}
<span class="hljs-selector-class">.mode-dark</span> <span class="hljs-selector-class">.blog-header</span> {
    <span class="hljs-attribute">position</span>: -webkit-sticky; <span class="hljs-comment">/* Safari support */</span>
    <span class="hljs-attribute">position</span>: sticky;
    <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;
}
</code></pre>
<p>There is no example of this because you are seeing the sticky header right now!</p>
<p>I've put all of the code on <a target="_blank" href="https://gist.github.com/aboutDavid/8ff3099228ae545394df9419f9ab15a6">GitHub Gists</a>.</p>
<p>Edit: I've decided not to do the custom headers until I fix a few things.</p>
]]></content:encoded></item><item><title><![CDATA[Making a portfolio using Webpack, 11ty, and Halfmoon]]></title><description><![CDATA[Table Of Contents

🛍 Resource Shopping/Setting up
📦 Webpack config
⚙ Setting up 11ty
👨‍💻 Coding our base templates
📄 Making the portfolio
🏭 Making it "production" ready
📔 Notes & Credits

🛍 Resource Shopping/Setting up
Ok, what do I mean by r...]]></description><link>https://blog.aboutdavid.me/making-a-portfolio-using-webpack-11ty-and-halfmoon</link><guid isPermaLink="true">https://blog.aboutdavid.me/making-a-portfolio-using-webpack-11ty-and-halfmoon</guid><category><![CDATA[Tutorial]]></category><category><![CDATA[webpack]]></category><dc:creator><![CDATA[David]]></dc:creator><pubDate>Thu, 22 Oct 2020 23:10:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1603408188565/MY4wmbLuv.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="table-of-contents">Table Of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#resource_shopping">🛍 Resource Shopping/Setting up</a></li>
<li><a class="post-section-overview" href="#webpack_config">📦 Webpack config</a></li>
<li><a class="post-section-overview" href="#11ty_setup">⚙ Setting up 11ty</a></li>
<li><a class="post-section-overview" href="#coding_base_templates">👨‍💻 Coding our base templates</a></li>
<li><a class="post-section-overview" href="#making_the_portfolio">📄 Making the portfolio</a></li>
<li><a class="post-section-overview" href="#making_it_production_ready">🏭 Making it "production" ready</a></li>
<li><a class="post-section-overview" href="#notes_and_credits">📔 Notes &amp; Credits</a></li>
</ul>
<h2 id="lessa-nameresourceshopping-hrefresourceshoppinggreater-resource-shoppingsetting-uplessagreater"><a href="#resource_shopping">🛍 Resource Shopping/Setting up</a></h2>
<p>Ok, what do I mean by resource shopping? We go around the internet looking ("shopping") for resources (e.g. Bootstrap, jQuery plugins, etc) that we will use in our project. For this mini-project, I've chosen:</p>
<ul>
<li><a target="_blank" href="https://gethalfmoon.com">Halfmoon</a> for our design</li>
<li><a target="_blank" href="https://11ty.dev/">11ty</a> to compile our base templates</li>
<li><a target="_blank" href="https://webpack.js.org/">Webpack</a> to compile our assets (Halfmoon, Sticky Sidebar, etc)</li>
<li>style-loader &amp; css-loader for Webpack so we can compile CSS</li>
</ul>
<p>Lets install their NPM packages for Webpack so we can bundle them up:</p>
<pre><code class="lang-sh">npm i @11ty/eleventy -g -s
npm i webpack webpack-cli -s -d
npm i halfmoon style-loader css-loader
</code></pre>
<p><strong>Note:</strong> Webpack 5.0.0-beta.1 and higher must use a node version higher than 10.13.0 (LTS). So, since I'm using Glitch to create this, I'm going to change in the package.json:</p>
<pre><code class="lang-json"><span class="hljs-string">"engines"</span>: { <span class="hljs-attr">"node"</span>: <span class="hljs-string">"10.x"</span> }
</code></pre>
<p>to </p>
<pre><code class="lang-json"><span class="hljs-string">"engines"</span>: { <span class="hljs-attr">"node"</span>: <span class="hljs-string">"12.x"</span> }
</code></pre>
<p>and add a .nvmrc (for netlify) with just <code>12.9.0</code>. If you are not using Netlify or Glitch, then just make sure you have a higher version installed.</p>
<p>Ok, we have our node versions setup and packages installed, lets start with webpack.</p>
<h2 id="lessa-hrefwebpackconfig-namewebpackconfiggreater-webpack-configlessagreater"><a href="#webpack_config">📦 Webpack config</a></h2>
<p>Projects that use a bunch of files probably should use something called Webpack. Webpack basically allows you to bundle your assets into 1 (or more) files for your browser. Pretty cool right?</p>
<p>Let's make a file called <code>webpack.config.js</code> with the following:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'development'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"bundle.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [<span class="hljs-string">"style-loader"</span>, <span class="hljs-string">"css-loader"</span>]
      }
    ]
  }
};
</code></pre>
<p>This basically says "Bundle the file src/index.js into .dist/bundle.js"
(oh and by the way, make the file <code>src/index.js</code> and the folder <code>dist</code> because we will need it in a moment)</p>
<p>In our src/index.js file, let's require our files/packages that we went over in <a href="#resource_shopping">Resource Shopping/Setting up</a> with this code:</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">require</span>(<span class="hljs-string">"halfmoon/css/halfmoon.min.css"</span>); <span class="hljs-comment">// require halfmoon.css</span>
<span class="hljs-built_in">window</span>.halfmoon = <span class="hljs-built_in">require</span>(<span class="hljs-string">"halfmoon"</span>); <span class="hljs-comment">// require halfmoon.js</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Webpack loaded!"</span>); <span class="hljs-comment">// Show in the console that the webpack bundle is loaded.</span>
</code></pre>
<p>Now we can bundle them together! Just run <code>webpack</code> and it should bundle your stuff together! Your bundle should be in <code>dist/bundle.js</code> if you made it right.</p>
<p>That's all you need to do to bundle your modules together.</p>
<h2 id="lessa-href11tysetup-name11tysetupgreater-setting-up-11tylessagreater"><a href="#11ty_setup">⚙ Setting up 11ty</a></h2>
<p>This will be a shorter section because 11ty does not need any config to run.</p>
<p>Make a folder called <code>_includes</code>. Then in that folder, make a file called <code>base.njk</code> with the following:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge,chrome=1"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"HandheldFriendly"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"true"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
{{ content | safe }}
<span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>That's right. <code>.njk</code> files (nunjuck files) use HTML! But, whats this <code>{{ content | safe }}</code> thing? Well, since <code>_includes/base.njk</code> is a layout, we can tell our pages (like index.njk) to use <code>_includes/base.njk</code> as a layout.</p>
<p>Now, we can make our <code>index.njk</code> file (which will be located at <code>/</code> when we compile it.) Lets just insert:</p>
<pre><code class="lang-md">---
<span class="hljs-section">layout: base.njk
---</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span>Hello!<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre>
<p>in that file. Before we run it, let's do some automation to make it easier for us to code our portfolio. In our <code>package.json</code> file add:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {<span class="hljs-attr">"start"</span>: <span class="hljs-string">"eleventy --serve --port=3000"</span>}
</code></pre>
<p>to your file. Now you can visit your demo site at locathost:3000 (or just your regular domain if you are using Glitch). It should look something like this:
<img src="https://dev-to-uploads.s3.amazonaws.com/i/r01ncvnzpmncfy4j2xz4.png" alt="hello_world" /></p>
<p>Yay! We have used successfully used 11ty layouts! One last thing: We need to make sure 11ty adds our bundle. So make a new file called <code>.eleventy.js</code> and add the following:</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">eleventyConfig</span>) </span>{
  eleventyConfig.addPassthroughCopy(<span class="hljs-string">"img"</span>);
  eleventyConfig.addPassthroughCopy(<span class="hljs-string">"dist"</span>);
};
</code></pre>
<p>This tells 11ty to allow the img folder and the dist folder.</p>
<h2 id="lessa-namecodeportfolio-hrefcodingbasetemplatesgreater-coding-our-base-templateslessagreater"><a href="#coding_base_templates">👨‍💻 Coding our base templates</a></h2>
<p>Ok, lets get into the design part! Go back to our base layout and include our bundle:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/bundle.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>HalfmoonCSS, HalfmoonJS, and Sticky Sidebar should now be included in your webpage!</p>
<p>Now, why don't we add a navbar? Like many sites, this allows your users to easily navigate your site.</p>
<p>Add the following code to your <code>_includes/base.njk</code> file inside the "body" tag:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge,chrome=1"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"HandheldFriendly"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"true"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">data-set-preferred-mode-onload</span>=<span class="hljs-string">"true"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- Navbar: https://www.gethalfmoon.com/docs/navbar/ --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"background-image:url('https://cdn.glitch.com/d4417ab9-7b55-405a-bfbf-6194880aa9f7%2Fmarek-piwnicki-bNnYAs5pXbw-unsplash.jpg?v=1603332064144');"</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Navbar brand --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-brand"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.glitch.com/d4417ab9-7b55-405a-bfbf-6194880aa9f7%2Fninja-cat_1f431-200d-1f464.png?v=1603305812684"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"..."</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Navbar nav --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-nav ml-auto"</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item active"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"halfmoon.toggleDarkMode();"</span>&gt;</span>🌙<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
{{ content | safe }}
<span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/bundle.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/i/c5tigjrrmyef5u66rfcw.png" alt="first demo" /></p>
<p>Hey! Did you see that 🌙 button? That's the darkmode toggle, which allows you to toggle on and off dark mode! It looks something like this:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/i/q53tygq4ta5dpck0klv8.png" alt="dark mode" /></p>
<p>Pretty cool right? You can trigger it yourself using:</p>
<pre><code class="lang-jsx">halfmoon.toggleDarkMode();
</code></pre>
<h2 id="lessa-hrefmakingtheportfolio-namemakingtheportfoliogreatermaking-the-portfolio-partlessagreater"><a href="#making_the_portfolio">📄Making the "portfolio" part</a></h2>
<p>Let's get rid of the "Hello" header:</p>
<pre><code class="lang-diff"><span class="hljs-comment">---</span>
layout: base.njk
<span class="hljs-comment">---</span>
<span class="hljs-deletion">- &lt;h1&gt;Hello!&lt;/h1&gt;</span>
</code></pre>
<p>We can now make "about me" cards and show off our knowledge of certain skills.</p>
<p>For this part, we will be using:</p>
<ul>
<li><a target="_blank" href="https://www.gethalfmoon.com/docs/progress/">Progress bars</a></li>
<li><a target="_blank" href="https://www.gethalfmoon.com/docs/containers/">Containers</a></li>
<li><a target="_blank" href="https://www.gethalfmoon.com/docs/content-and-cards/">Cards</a>.</li>
</ul>
<p>Make a new file called "about.njk":</p>
<pre><code class="lang-md">---
<span class="hljs-section">eleventyExcludeFromCollections: true
---</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container-fluid"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding-left: 5px;"</span>&gt;</span></span>
<span class="hljs-code">    &lt;div class="card"&gt;
        &lt;h4&gt;Who am I?&lt;/h4&gt;
        &lt;img src="https://cdn.glitch.com/d4417ab9-7b55-405a-bfbf-6194880aa9f7%2Fwilliam-recinos-qtYhAQnIwSE-unsplash.jpg" width="225" height="150" /&gt;
        &lt;p&gt;My name is John Doe. I am a freelance web devoloper with many years of expierence. I also play the violin the my spare time.&lt;/p&gt;
        &lt;h2 class="card-title"&gt;Skills&lt;/h2&gt;
        &lt;p&gt;HTML&lt;/p&gt;
        &lt;div class="progress"&gt;
            &lt;div class="progress-bar" style="width: 78%;" role="progressbar" aria-valuenow="78" aria-valuemin="0" aria-valuemax="100"&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;p&gt;CSS&lt;/p&gt;
        &lt;div class="progress"&gt;
            &lt;div class="progress-bar" style="width: 64%;" role="progressbar" aria-valuenow="54" aria-valuemin="0" aria-valuemax="100"&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;p&gt;Javascript&lt;/p&gt;
        &lt;div class="progress"&gt;
            &lt;div class="progress-bar" style="width: 54%;" role="progressbar" aria-valuenow="54" aria-valuemin="0" aria-valuemax="100"&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;p&gt;Ruby&lt;/p&gt;
        &lt;div class="progress"&gt;
            &lt;div class="progress-bar" style="width: 32%;" role="progressbar" aria-valuenow="32" aria-valuemin="0" aria-valuemax="100"&gt;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;</span>
</code></pre>
<p>And add this to your main index.njk file:</p>
<pre><code>{% <span class="hljs-keyword">include</span> "about.njk" %}
</code></pre><p>this should include the about.njk file into the index.njk file. </p>
<p>You should see something like this:
<img src="https://dev-to-uploads.s3.amazonaws.com/i/8c96t777ycwtwem3ukcl.png" alt="about cards" /></p>
<p>You can add new skill bars by adding this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Skill Name<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"progress"</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"progress-bar"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width: value%"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"progressbar"</span> <span class="hljs-attr">aria-valuenow</span>=<span class="hljs-string">"value"</span> <span class="hljs-attr">aria-valuemin</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">aria-valuemax</span>=<span class="hljs-string">"100"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Alright looking good. We also want to show off our projects as any good web developer would do. </p>
<p>Make a new file called "projects.njk" and add the following:</p>
<pre><code class="lang-md">---
<span class="hljs-section">eleventyExcludeFromCollections: true
---</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container-fluid"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"padding-left: 5px;"</span>&gt;</span></span>
<span class="hljs-code">    &lt;div class="card"&gt;
        &lt;h4&gt;Projects:&lt;/h4&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href="#"&gt;&lt;b&gt;Project one:&lt;/b&gt;&lt;/a&gt; Project description&lt;/li&gt;
            &lt;li&gt;&lt;a href="#"&gt;&lt;b&gt;Project two:&lt;/b&gt;&lt;/a&gt; Project description&lt;/li&gt;
            &lt;li&gt;&lt;a href="#"&gt;&lt;b&gt;Project three:&lt;/b&gt;&lt;/a&gt; Project description&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;
&lt;/div&gt;</span>
</code></pre>
<p>Now we can modify our index.njk file to look like this:</p>
<pre><code class="lang-diff">{% include "about.njk" %}
<span class="hljs-addition">+</span>
<span class="hljs-addition">+ {% include "projects.njk" %}</span>
</code></pre>
<p>Great! Now we the about section and our project showcase. We now have a semi-portfolio using Webpack. </p>
<h2 id="lessa-hrefmakingitproductionready-namemakingitproductionreadygreater-making-it-production-readylessagreater"><a href="#making_it_production_ready">🏭 Making it "production" ready</a></h2>
<p>Ok, let's make it production ready. Bascially, Polishing every thing up, doing some SEO, etc.</p>
<h4 id="changing-webpack-settings">Changing webpack settings</h4>
<p>The webpack bundle we made is huge! So let's tell webpack to remove extra stuff and compress the file. Go into the webpack.config.js file and modify it slightly:</p>
<pre><code class="lang-diff">const path = require("path");
<span class="hljs-addition">+ const { CleanWebpackPlugin } = require("clean-webpack-plugin");</span>
module.exports = {
  entry: "./src/index.js",
<span class="hljs-deletion">-  mode: "development",</span>
<span class="hljs-addition">+  mode: "production",</span>
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },
<span class="hljs-addition">+  plugins: [new CleanWebpackPlugin()]</span>
};
</code></pre>
<p>Oh and don't forget to install clean-webpack-plugin, which deletes your old bundle so no old data is stored.</p>
<pre><code class="lang-sh">npm i clean-webpack-plugin
</code></pre>
<p>You may now run <code>webpack</code> and you should now have a production ready bundle!</p>
<h4 id="improving-seo-sitemap">Improving SEO: Sitemap</h4>
<p>Lets make a sitemap. This should allow us to submit the portfolio to Google easier (<a target="_blank" href="https://github.com/11ty/eleventy-base-blog/blob/master/sitemap.xml.njk">source</a>):</p>
<pre><code class="lang-html">---
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">urlset</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.sitemaps.org/schemas/sitemap/0.9"</span>&gt;</span>
{%- for page in collections.all %}
  {% set absoluteUrl %}{{ page.url | url  }}{% endset %}
  <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">loc</span>&gt;</span>https://{{ metadata.domain }}{{ absoluteUrl }}<span class="hljs-tag">&lt;/<span class="hljs-name">loc</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span>
{%- endfor %}
<span class="hljs-tag">&lt;/<span class="hljs-name">urlset</span>&gt;</span>
</code></pre>
<h4 id="improving-seo-metatags">Improving SEO: Metatags</h4>
<p>Metatags allow for website previews. They give your users a preview of your website without having to see it. Sort of like a "try before you buy" thing. You can easily generate some easily with <a target="_blank" href="https://metatags.io/">metatags.io</a>. They look like this:</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- Primary Meta Tags --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Demo portfolio: The portfolio of John doe<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Demo portfolio: The portfolio of John doe"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"My name is John Doe. I have a bunch of experience with HTML, CSS, JavaScript and Ruby."</span>&gt;</span>

<span class="hljs-comment">&lt;!-- Open Graph / Facebook --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"website"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:url"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"https://demo-portfolio-11ty.glitch.me/"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Demo portfolio: The portfolio of John doe"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"My name is John Doe. I have a bunch of experience with HTML, CSS, JavaScript and Ruby."</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:image"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"[IMAGE]"</span>&gt;</span>

<span class="hljs-comment">&lt;!-- Twitter --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"twitter:card"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"summary_large_image"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"twitter:url"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"https://demo-portfolio-11ty.glitch.me/"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"twitter:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Demo portfolio: The portfolio of John doe"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"twitter:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"My name is John Doe. I have a bunch of experience with HTML, CSS, JavaScript and Ruby."</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"twitter:image"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"[IMAGE]"</span>&gt;</span>
</code></pre>
<h4 id="compressing-your-html">Compressing your HTML</h4>
<p>This is pretty easy to do. First install html-minifier with NPM:</p>
<pre><code class="lang-sh">npm i html-minifier
</code></pre>
<p>Add the following snippet to .eleventy.js:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> htmlmin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-minifier"</span>);
eleventyConfig.addTransform(<span class="hljs-string">"htmlmin"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">content, outputPath</span>) </span>{
    <span class="hljs-keyword">if</span> (outputPath.endsWith(<span class="hljs-string">".html"</span>) || outputPath.endsWith(<span class="hljs-string">".css"</span>) || outputPath.endsWith(<span class="hljs-string">".js"</span>)) {
        <span class="hljs-keyword">let</span> minified = htmlmin.minify(content, {
            <span class="hljs-attr">useShortDoctype</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">removeComments</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">collapseWhitespace</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">minifyJS</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">minifyCSS</span>: <span class="hljs-literal">true</span>,
        });
        <span class="hljs-keyword">return</span> minified;
    }

    <span class="hljs-keyword">return</span> content;
});
</code></pre>
<p>This tells 11ty to use html-minifier to compress HTML, JavaScript, and CSS files.
<img src="https://i.imgur.com/yHF7gBJ.png" alt="compressed html" /></p>
<p>Looking good!</p>
<h2 id="lessa-hrefnotesandcredits-namenotesandcreditsgreater-notes-and-creditslessagreater"><a href="#notes_and_credits">📔 Notes &amp; Credits</a></h2>
<p>In this tutorial, we used Webpack to bundle assets (a simple bundle at that), 11ty to make our portfolio, and Halfmoon for the main design.</p>
<p>Thanks to @khalby786 for making <a target="_blank" href="https://brockly.glitch.me/">brockly</a>, which made the browser-like previews.</p>
<p>Some snippets of code (such as the sitemap and html mimifier came from <a target="_blank" href="https://github.com/11ty/eleventy-base-blog/blob/master/sitemap.xml.njk">11ty/eleventy-base-blog</a> and the <a target="_blank" href="https://www.11ty.dev/docs/">11ty docs</a>.</p>
<p>You can get a ready made version on Glitch by clicking <a target="_blank" href="https://glitch.com/edit/#!/remix/demo-portfolio-11ty">here</a> (make an account and edit the _data/metadata.json file)</p>
<p>You can see the demo <a target="_blank" href="https://demo-portfolio-11ty.glitch.me/">here</a></p>
]]></content:encoded></item><item><title><![CDATA[Calculating Read time in JavaScript]]></title><description><![CDATA[Note: This blog was originally published on my website. 
This is a very simple task. First, we need a sentence to try this out. Let's use "The quick brown fox jumps over the lazy dog".  A few thing we need to know is:

The average word is 5 in the En...]]></description><link>https://blog.aboutdavid.me/calculating-read-time-in-javascript</link><guid isPermaLink="true">https://blog.aboutdavid.me/calculating-read-time-in-javascript</guid><dc:creator><![CDATA[David]]></dc:creator><pubDate>Thu, 08 Oct 2020 20:03:33 GMT</pubDate><content:encoded><![CDATA[<p>Note: This blog was originally published on my website. </p>
<p>This is a very simple task. First, we need a sentence to try this out. Let's use "The quick brown fox jumps over the lazy dog".  A few thing we need to know is:</p>
<ul>
<li>The average word is 5 in the English dictionary.</li>
<li>The average Words Per Minute for reading (WPM) is 200-250, which averages to 225 WPM. (<a target="_blank" href="https://archive.is/FRfWJ">https://archive.is/FRfWJ</a>).</li>
</ul>
<p>So, we have to split the text every 5 letters and divide it by 225 WPM. This can easily be done with JavaScript:</p>
<pre><code class="lang-jsx"><span class="hljs-string">"The quick brown fox jumps over the lazy dog."</span>.match(<span class="hljs-regexp">/.{1,5}/g</span>).length/<span class="hljs-number">225</span>;
</code></pre>
<p>Which should return a value of <code>0.04</code>. So are we done? No. We also need make it human readable. First we need to round to the nearest whole number by using <code>Math.round()</code> :</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">Math</span>.round(<span class="hljs-string">"The quick brown fox jumps over the lazy dog."</span>.match(<span class="hljs-regexp">/.{1,5}/g</span>).length/<span class="hljs-number">225</span>);
</code></pre>
<p>Which should return <code>0</code>. Now we are almost done. Let's make it human readable. We can give it summaries using if/else statements. </p>
<p>Lets use:</p>
<ul>
<li>Less than a minute read - for read times under a minute.</li>
<li><code>n</code> min read - for read times that are over a minute.</li>
</ul>
<p>as statements.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">var</span> rt = <span class="hljs-built_in">Math</span>.round(<span class="hljs-string">"The quick brown fox jumps over the lazy dog."</span>.match(<span class="hljs-regexp">/.{1,5}/g</span>).length/<span class="hljs-number">225</span>);
  <span class="hljs-keyword">if</span> (rt &lt;= <span class="hljs-number">0</span>) {
  rt = <span class="hljs-string">"Less than a minute read."</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (rt === <span class="hljs-number">1</span>){
  rt = <span class="hljs-string">`<span class="hljs-subst">${rt}</span> min read.`</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(rt)){
  rt = <span class="hljs-string">"Failed to calculate readtime!"</span>
  } <span class="hljs-keyword">else</span> {
  rt = <span class="hljs-string">"Failed to calculate readtime!"</span>
  }
</code></pre>
<p>which returns <code>Less than a minute read.</code></p>
<p>Let's make it ready for "production" by wrapping it around a function and compressing it using <a target="_blank" href="https://jscompress.com/">JScompress</a>. I put the source code on <a target="_blank" href="https://dev.to/aboutdavid/p2pbin-a-peer-to-peer-paste-sharing-site-with-no-servers-2f8c">P2Pbin</a>, which you can find <a target="_blank" href="https://p2pbin.glitch.me/?id=QmSUskuMStqUSb4huDVDWc94UPE3v5AyX2aNp4nUoWw9tp">here.</a></p>
]]></content:encoded></item><item><title><![CDATA[Why you should try IPFS]]></title><description><![CDATA[Today, I will try to convince you to at least try IPFS.
Integrity built in.
Let me explain the difference between content-based addressing and location-based addressing. This will help you understand how the integrity works:

Location-based addressin...]]></description><link>https://blog.aboutdavid.me/why-you-should-try-ipfs</link><guid isPermaLink="true">https://blog.aboutdavid.me/why-you-should-try-ipfs</guid><dc:creator><![CDATA[David]]></dc:creator><pubDate>Sun, 04 Oct 2020 02:54:57 GMT</pubDate><content:encoded><![CDATA[<p>Today, I will try to convince you to at least try IPFS.</p>
<h3 id="integrity-built-in">Integrity built in.</h3>
<p>Let me explain the difference between content-based addressing and location-based addressing. This will help you understand how the integrity works:</p>
<ul>
<li>Location-based addressing is where a client would know exactly where a file is. </li>
<li>Content-based addressing is where a client would ask what the contents of a file is, verifying the contents were not modified using a hash. So, unlike Location-based addressing (HTTP), it has more security.</li>
</ul>
<h3 id="peer-to-peer-file-storage">Peer-to-Peer file storage</h3>
<p>You can say goodbye to those servers hosting your data (such as AWS S3 and Google Drive) and say hello to Peers! What is a peer? Peers can be a client, and a server. They can replace servers if there are enough of them. Why peers instead of a server? If a peer goes down, other peers can give you the data you need. But if a server goes down, that data is gone until the server is back up.</p>
<h3 id="a-programmatic-api">A programmatic API.</h3>
<p>Like many things, it has an API. From running a node (peer) on your web browser (<a target="_blank" href="https://js.ipfs.io/">js-ipfs</a>) to interacting with nodes hosted on a user's computer (See their docs for their <a target="_blank" href="https://docs.ipfs.io/reference/http/api">HTTP API</a>).</p>
<p>Those were some things I wanted to talk about because not many people are willing to try IPFS. If you want to learn more about IPFS, you can check out the (many) links below:</p>
<ul>
<li><a target="_blank" href="https://awesome.ipfs.io/">Awesome IPFS - a awesome list of projects that are made/are using IPFS.</a></li>
<li><a target="_blank" href="https://ipfs.io/">ipfs.io - The main website for IPFS</a></li>
<li><a target="_blank" href="https://ipfs.io/#install">Install IPFS</a></li>
<li><a target="_blank" href="https://docs.ipfs.io/">IPFS docs - The official docs for IPFS. They have many tutorials on how to deploy websites to IPFS and how to install IPFS</a></li>
<li><a target="_blank" href="https://github.com/ipfs/js-ipfs/tree/master/examples/browser-script-tag">Get started with IPFS in the browser</a></li>
<li><a target="_blank" href="https://github.com/ipfs/js-ipfs/tree/master/examples/ipfs-101">Get started with IPFS in Node.js</a></li>
</ul>
]]></content:encoded></item></channel></rss>