<?xml version='1.0' encoding='UTF-8' ?>
<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom' xmlns:content='http://purl.org/rss/1.0/modules/content/'>
<channel>
<atom:link href="https://maw.sh/rss.xml" rel="self" type="application/rss+xml" />
<title>Mahmoud Ashraf</title>
<description>Mahmoud Ashraf is a Front-end developer based in Alexandria, Egypt.</description>
<link>https://maw.sh/</link>
<item>
<title>Uninstall all neovim plugins</title>
<guid>https://maw.sh/blog/uninstall-all-neovim-plugins</guid>
<link>https://maw.sh/blog/uninstall-all-neovim-plugins</link>
<pubDate>Fri, 02 Dec 2022 00:00:00 +0000</pubDate>
<description>This Article about using neovim on a Unix way.</description>
<content:encoded><![CDATA[
<h1 id="uninstall-all-neovim-plugins">Uninstall all neovim plugins</h1>
<figure>
<img src="matrix.jpg" alt="the matrix movie scene" />
<figcaption aria-hidden="true">the matrix movie scene</figcaption>
</figure>
<p>As a developer, you need a robust environment that fits your needs to
develop, compile, debug, build, and so on. So, you have now two pills to
choose one of them. And most probably if you read this article you have
already chosen the red one. But unfortunately, Neovim plugins does not
give you the full control of the experience.</p>
<h2 id="why-vimneovim-and-not-vscodeintellij">Why vim/neovim and not
vscode/intellij?</h2>
<p>I choose vim/neovim because I need a “just” code editor, and also it
can be easily leverage my tools capabilities on UNIX way, and you can
read more on this article <a
href="https://blog.sanctum.geek.nz/series/unix-as-ide/">Unix as an
IDE</a>, but the all-in-solutions, like an IDE, is not the right tool
for code editing, it came with a lot of features and defaults that you
in most cases I don’t need it, or I have to learn how to use them
according to that IDE.</p>
<h2 id="so-why-neovim-not-vim">So, Why neovim not vim?</h2>
<p>I used to use vim before, but I need an editor that more focused
natively on “code”, Not just a plain text, So neovim is a good choice
for developers to enhance the coding experience by using lsp, and
treesitter.</p>
<h2 id="immature-plugin-ecosystem">immature plugin ecosystem</h2>
<p>To be honest, one of the problems on the neovim community is nonsense
plugins that just a replicate vim plugins or plugins that do what we
should do in the terminals but using lua as plugin on neovim. Also, It
used at the beginning to be missing the help documentation but now I
believe it gets better, so it is nice.</p>
<p>Also, what they called “neovim distributions” which another layer of
complexity that tight your use by using the author setting file.</p>
<h2 id="how-to-escape-and-use-neovim-on-unix-way">How to escape, and use
neovim on unix way</h2>
<p>What I’ve done is first delete all my plugins, and start with a clean
<code>init.lua</code> file with simple configuration, and gradually see
what I’m really miss and add it into my config.</p>
<p>If the feature that I need can be easily implemented with neovim
config only I’ll go to this direction, but if not I’ll search for small
and well-written and well-documented plugin and also if it has a lot of
features, I’ll go first to copy-paste code into my neovim config and
start tweaking it.</p>
<h2 id="examples-time">Examples time</h2>
<h4 id="searchbrowse-files">- search/browse files:</h4>
<p>for the codebase navigation I’ll use the vim <code>find</code>,
<code>buffers</code> commands but instead of using
<code>vim.opt.path:append "*"</code> which leads to hang the command on
projects that’s have for example <code>node_module</code> I will use the
local <code>.nvimrc</code> on each project to extend my config</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Load .nvimrc manually</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">local</span> local_vimrc <span class="op">=</span> vim<span class="op">.</span>fn<span class="op">.</span>getcwd<span class="op">()</span> <span class="op">..</span> <span class="st">&#39;/.nvimrc.lua&#39;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> vim<span class="op">.</span>loop<span class="op">.</span>fs_stat<span class="op">(</span>local_vimrc<span class="op">)</span> <span class="cf">then</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">local</span> source <span class="op">=</span> vim<span class="op">.</span>secure<span class="op">.</span>read<span class="op">(</span>local_vimrc<span class="op">)</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="kw">not</span> source <span class="cf">then</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">end</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  vim<span class="op">.</span>cmd<span class="op">(</span><span class="fu">string.format</span><span class="op">(</span><span class="st">&#39;so %s&#39;</span><span class="op">,</span> local_vimrc<span class="op">))</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="cf">end</span></span></code></pre></div>
<p>so on the project root directory I can create a new file
<code>.nvimrc.lua</code> and add this line e.g:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>vim<span class="op">.</span>opt<span class="op">.</span>path<span class="op">:</span>append<span class="op">({</span> <span class="st">&quot;src/**&quot;</span><span class="op">,</span> <span class="op">})</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- and any config that I need for this project</span></span></code></pre></div>
<p>And for search on the files there is a vim <code>grep</code> command
with some modification that makes it work more performant by using <a
href="/blog/my-terminal-became-more-rusty/#ripgrep">ripgrep</a></p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- better grip with &#39;rg&#39;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> vim<span class="op">.</span>fn<span class="op">.</span>executable <span class="st">&#39;rg&#39;</span> <span class="op">==</span> <span class="dv">1</span> <span class="cf">then</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  o<span class="op">.</span>grepprg <span class="op">=</span> <span class="vs">[[rg --hidden --smart-case --vimgrep]]</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  o<span class="op">.</span>grepformat <span class="op">=</span> <span class="op">{</span> <span class="st">&#39;%f:%l:%c:%m&#39;</span> <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="cf">end</span></span></code></pre></div>
<p>and the nice about grep that the result now on your quickfix, so you
can easily navigate between them, and do any operation that you
want.</p>
<figure>
<img src="quickfix-vim-screenshot.jpg"
alt="a screenshot of neovim with quickfix opend" />
<figcaption aria-hidden="true">a screenshot of neovim with quickfix
opend</figcaption>
</figure>
<p>And here is my mapping, it may be useful, and here is the <a
href="https://github.com/22mahmoud/nvim/blob/master/lua/ma/utils.lua">utils</a>
used in the snippets below:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode lua"><code class="sourceCode lua"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- navigation &amp; find &amp; search</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;p&#39;</span><span class="op">,</span> <span class="st">&#39;:find&lt;space&gt;&#39;</span><span class="op">,</span> <span class="op">{</span> silent <span class="op">=</span> <span class="kw">false</span> <span class="op">})</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;rg&#39;</span><span class="op">,</span> <span class="st">&#39;:silent grep &quot;&quot;&lt;left&gt;&#39;</span><span class="op">,</span> <span class="op">{</span> silent <span class="op">=</span> <span class="kw">false</span> <span class="op">})</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;gw&#39;</span><span class="op">,</span> <span class="st">&#39;:silent grep &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- buffers</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;bn&#39;</span><span class="op">,</span> <span class="st">&#39;:bn&lt;cr&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;bp&#39;</span><span class="op">,</span> <span class="st">&#39;:bp&lt;cr&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;bl&#39;</span><span class="op">,</span> <span class="st">&#39;:ls t&lt;cr&gt;:b&lt;space&gt;&#39;</span><span class="op">,</span> <span class="op">{</span> silent <span class="op">=</span> <span class="kw">false</span> <span class="op">})</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;bd&#39;</span><span class="op">,</span> <span class="st">&#39;:bd!&lt;cr&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="co">-- quick list</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;qn&#39;</span><span class="op">,</span> <span class="st">&#39;:cn&lt;cr&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;qp&#39;</span><span class="op">,</span> <span class="st">&#39;:cp&lt;cr&gt;&#39;</span><span class="op">)</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;ql&#39;</span><span class="op">,</span> <span class="cn">G</span><span class="op">.</span>toggle_qf<span class="op">,</span> <span class="op">{</span> nowait <span class="op">=</span> <span class="kw">false</span> <span class="op">})</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a><span class="cn">G</span><span class="op">.</span>nnoremap<span class="op">(</span><span class="st">&#39;&lt;leader&gt;qq&#39;</span><span class="op">,</span> <span class="st">&#39;:cex []&lt;cr&gt;&#39;</span><span class="op">)</span></span></code></pre></div>
<h3 id="code-completion">- code completion</h3>
<p>I’m kinda person that doesn’t like a destruction while typing, so
fuzzy finder, and auto pop-up menus not a good solution for me. I prefer
to go also with the native <a
href="https://neovim.io/doc/user/insert.html#ins-completion">ins-compilation</a>
and use completion menu on demand by a specific category.</p>
<h3 id="statuslinewinbar">- statusline/winbar</h3>
<p>For this one I need it very simple so I write it by myself after I
submit this <a
href="https://old.reddit.com/r/neovim/comments/q3jur8/please_share_your_statusline_config_lua_no/">post</a>
on <code>/r/neovim</code> sub-reddit and get a lot of inspiration.</p>
<h3 id="git">- Git</h3>
<p>Why should I integrate git inside neovim! I use git on my terminal
inside tmux session using some helpful commands that fits on my
workflow. and that is on of them:</p>
<pre class="shell"><code># `-p` will open interactive mode to add/reset based on the hunks
git add -p
git reset -p</code></pre>
<figure>
<img src="hunks-screenshot.jpg"
alt="a screenshot of git add -p command" />
<figcaption aria-hidden="true">a screenshot of <code>git add -p</code>
command</figcaption>
</figure>
<h3 id="neovim-goodies-lsptreesitter">- Neovim goodies
(lsp/treesitter)</h3>
<p>This is the part that I’m really have to use official plugins so
let’s install packer… Or wait a minute, why not just use the native
solution.</p>
<p>there is a <a
href="https://neovim.io/doc/user/repeat.html#packages">vim packages</a>
is a directory you can download your plugins inside it and just it
nothing more to do.</p>
<pre class="shell"><code>cd ~/.local/share/nvim
git init .
git submodule init
mkdir site/pack/plugins/opt/
git submodule add --depth 1 https://github.com/neovim/nvim-lspconfig site/pack/plugins/opt/nvim-lspconfig</code></pre>
<p>and I wrote a wrapper on <code>lua</code> to make the process easy
and similar to the package managers <a
href="https://github.com/22mahmoud/nvim/blob/master/lua/ma/plugins.lua">check
it out</a></p>
<h3 id="theming">- Theming</h3>
<p>I just use <a
href="https://github.com/RRethy/nvim-base16">nvim-base16</a> plugin to
fit my base16 theme system.</p>
<h2 id="conclusion">conclusion</h2>
<p>After adding all my needs I find out that there was many plugins on
my config that does not help me or not fit on my workflow. e.g: I do not
use snippets, file explorer, fuzzy finders.</p>
]]></content:encoded>
</item>
<item>
<title>Adevnt of Code 2020</title>
<guid>https://maw.sh/blog/adevnt-of-code-2020</guid>
<link>https://maw.sh/blog/adevnt-of-code-2020</link>
<pubDate>Fri, 04 Dec 2020 00:00:00 +0000</pubDate>
<description>advent of code solutions by @22mahmoud</description>
<content:encoded><![CDATA[
<h1 id="advent-of-code-2020">Advent of Code 2020</h1>
<p>This blog will be updated every day to show you my solutions for <a
href="https://adventofcode.com/">aoc-2020</a>.</p>
<h2 id="toc">TOC</h2>
<ul>
<li><a href="#Day%2001">day 01</a> <em>⭐⭐</em></li>
<li><a href="#Day%2002">day 02</a> <em>⭐⭐</em></li>
<li>day 03</li>
<li>day 04</li>
<li>day 05</li>
<li>day 06</li>
<li>day 07</li>
<li>day 08</li>
<li>day 09</li>
<li>day 10</li>
<li>day 11</li>
<li>day 12</li>
<li>day 13</li>
<li>day 14</li>
<li>day 15</li>
<li>day 16</li>
<li>day 17</li>
<li>day 18</li>
<li>day 19</li>
<li>day 20</li>
<li>day 21</li>
<li>day 22</li>
<li>day 23</li>
<li>day 24</li>
<li>day 25</li>
</ul>
<hr />
<h2 id="day-01">Day 01</h2>
<p>[<a href="#part%2001%20⭐">part 01</a> - <a
href="#part%2002%20⭐">part 02</a>]</p>
<h3 id="part-01">part 01 ⭐</h3>
<p>The first part of day one is a two-sum problem needs to get the
multiply of two entries that sum to <code>2020</code></p>
<p>The naive solution you can do two loops and make a condition whenever
the two numbers sum to <code>2020</code> break the loop and return the
value.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">p1</span>(input) {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> i<span class="op">++</span>)</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> j <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> j<span class="op">++</span>)</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> (input[i] <span class="op">+</span> input[j] <span class="op">===</span> <span class="dv">2020</span>) <span class="cf">return</span> input[i] <span class="op">*</span> input[j]<span class="op">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>This solution will take <code>O(n^2)</code> time complexity for each
element.</p>
<p>We can enhance our solution by using <code>Map</code> data structure
and only one loop</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">p1</span>(input) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> map <span class="op">=</span> <span class="kw">new</span> <span class="bu">Map</span>()<span class="op">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) {</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> complement <span class="op">=</span> <span class="dv">2020</span> <span class="op">-</span> input[i]<span class="op">;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (map<span class="op">.</span><span class="fu">has</span>(complement)) <span class="cf">return</span> input[map<span class="op">.</span><span class="fu">get</span>(complement)] <span class="op">*</span> input[i]<span class="op">;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    map<span class="op">.</span><span class="fu">set</span>(input[i]<span class="op">,</span> i)<span class="op">;</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>this solution will take <code>O(n)</code> time complexity by traverse
the list containing <code>n</code> element only once.</p>
<h3 id="part-02">part 02 ⭐</h3>
<p>The difference in the part two that we need to get the multiply for
<code>three</code> numbers that sum to <code>2020</code></p>
<p>We can use the same naive solution by using brute force with three
loops.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">p2</span>(input) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> i<span class="op">++</span>)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> j <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> j<span class="op">++</span>)</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">for</span> (<span class="kw">let</span> k <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> k <span class="op">&lt;</span> input<span class="op">.</span><span class="at">length</span><span class="op">;</span> k<span class="op">++</span>)</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> (input[i] <span class="op">+</span> input[j] <span class="op">+</span> input[k] <span class="op">===</span> <span class="dv">2020</span>)</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>          <span class="cf">return</span> input[i] <span class="op">*</span> input[j] <span class="op">*</span> input[k]<span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<hr />
<h2 id="day-02">Day 02</h2>
<p>[<a href="#part%2001%20⭐-2">part 01</a> - <a
href="#part%2002%20⭐-2">part 02</a>]</p>
<h3 id="part-01-1">part 01 ⭐</h3>
<p>We have a list of passwords with validation rules, So we should
validate each password and submit the total number of valid
passwords.</p>
<pre><code>1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc</code></pre>
<p>First, let’s create an parser to extract information from each
line.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> getPasswordsList <span class="op">=</span> () <span class="kw">=&gt;</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">readFileSync</span>(path<span class="op">.</span><span class="fu">resolve</span>(<span class="bu">__dirname</span><span class="op">,</span> <span class="st">&#39;input.txt&#39;</span>)<span class="op">,</span> <span class="st">&#39;utf8&#39;</span>)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">split</span>(<span class="st">&#39;</span><span class="sc">
</span><span class="st">&#39;</span>)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">filter</span>(<span class="bu">Boolean</span>)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">map</span>((i) <span class="kw">=&gt;</span> i<span class="op">.</span><span class="fu">split</span>(<span class="ss">/</span><span class="sc">[-,:,\s]+</span><span class="ss">/</span>))<span class="op">;</span></span></code></pre></div>
<p>We read the <code>input.txt</code> file and convert it into an array
by split each line using <code>.split(
)</code> then we will use regex
to extract min, max, target, and password on each line by using multi
separator: <code>-</code>, <code>:</code>, and <code>\s</code> for
space.</p>
<p>If you interred to learn more about split with regex I highly
recommend to watch <a
href="https://www.youtube.com/watch?v=fdyqutmcI2Q">Regular Expressions:
split() - Programming with Text</a> video.</p>
<p>Now we are ready to write the validator function:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">getValidPasswordsP1</span>(passwords) {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> passwords<span class="op">.</span><span class="fu">reduce</span>((ans<span class="op">,</span> [min<span class="op">,</span> max<span class="op">,</span> letter<span class="op">,</span> password]) <span class="kw">=&gt;</span> {</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> count <span class="op">=</span> password<span class="op">.</span><span class="fu">match</span>(<span class="kw">new</span> <span class="bu">RegExp</span>(letter<span class="op">,</span> <span class="st">&#39;g&#39;</span>))<span class="op">?.</span><span class="at">length</span><span class="op">;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> count <span class="op">&gt;=</span> <span class="op">+</span>min <span class="op">&amp;&amp;</span> count <span class="op">&lt;=</span> <span class="op">+</span>max <span class="op">?</span> <span class="op">++</span>ans <span class="op">:</span> ans<span class="op">;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  }<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h3 id="part-02-1">part 02 ⭐</h3>
<p>Actually the part two is a lot easier than the part one it assume the
first two numbers are the positions for the target letter to only occurs
in one of them.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">getValidPasswordsP2</span>(passwords) {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> passwords<span class="op">.</span><span class="fu">reduce</span>((ans<span class="op">,</span> [pos1<span class="op">,</span> pos2<span class="op">,</span> letter<span class="op">,</span> password]) <span class="kw">=&gt;</span> {</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> (password<span class="op">.</span><span class="fu">charAt</span>(<span class="op">+</span>pos1 <span class="op">-</span> <span class="dv">1</span>) <span class="op">===</span> letter) <span class="op">^</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>      (password<span class="op">.</span><span class="fu">charAt</span>(<span class="op">+</span>pos2 <span class="op">-</span> <span class="dv">1</span>) <span class="op">===</span> letter)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">?</span> <span class="op">++</span>ans</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">:</span> ans<span class="op">;</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  }<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Use the bitwise <code>XOR</code> to make sure it only occurs in only
exact one position. you can check the MDN <a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR">reference</a>.</p>
]]></content:encoded>
</item>
<item>
<title>My terminal became more Rusty 🦀</title>
<guid>https://maw.sh/blog/my-terminal-became-more-rusty</guid>
<link>https://maw.sh/blog/my-terminal-became-more-rusty</link>
<pubDate>Fri, 21 Aug 2020 00:00:00 +0000</pubDate>
<description>CLI tools written in rust make my terminal fast and productive</description>
<content:encoded><![CDATA[
<h1 id="my-terminal-became-more-rusty">My terminal became more Rusty
🦀</h1>
<figure>
<img src="cover.jpeg" alt="big crap attack the city" />
<figcaption aria-hidden="true">big crap attack the city</figcaption>
</figure>
<p>As a Software-Engineer I spent most of the time inside my terminal,
So I need for that a fast terminal with fast tools to speed up my
productivity.</p>
<p>The tools written in rust help me to achieve that. let’s see in this
article those tools.</p>
<blockquote>
<h2 id="tldr">tl;dr</h2>
<ul>
<li><a href="https://github.com/alacritty/alacritty">alacritty</a> A
cross-platform, GPU-accelerated terminal emulator</li>
<li><a href="https://github.com/starship/starship">starship</a> 🌌 The
minimal, blazing-fast, and infinitely customizable prompt for any
shell!</li>
<li><a href="https://github.com/ogham/exa">exa</a> A modern version of
‘ls’.</li>
<li><a href="https://github.com/sharkdp/bat">bat</a> A cat(1) clone with
wings.</li>
<li><a href="https://github.com/dandavison/delta">delta</a> A viewer for
git and diff output</li>
<li><a href="https://github.com/ajeetdsouza/zoxide">zoxide</a> A faster
way to navigate your filesystem</li>
<li><a href="https://github.com/burntsushi/ripgrep">ripgrep</a> ripgrep
recursively searches directories for a regex pattern</li>
<li><a href="https://github.com/sharkdp/fd">fd</a> A simple, fast and
user-friendly alternative to ‘find’</li>
<li><a href="https://github.com/clementtsang/bottom">bottom</a> Yet
another cross-platform graphical process/system monitor.</li>
<li><a href="https://github.com/tldr-pages/tldr">tldr</a> 📚
Collaborative cheatsheets for console commands</li>
<li><a href="https://github.com/rigellute/spotify-tui">spotify-tui</a>
Spotify for the terminal written in Rust 🚀</li>
<li><a href="https://github.com/extrawurst/gitui">gitui</a> Blazing 💥
fast terminal-ui for git written in rust 🦀</li>
</ul>
</blockquote>
<h2 id="alacritty">Alacritty</h2>
<p>Let’s start our list with alacritty terminal is one of the fastest
terminals because of using GPU for rendering, and it is a cross-platform
terminal.</p>
<p>You can customize your own configuration like color scheme, fonts,
opacity, and key mapping.</p>
<p>Alacritty doesn’t come with ligature support but you can use this <a
href="https://github.com/zenixls2/alacritty/tree/ligature">fork</a>. or
if you are using Arch you can install it from <a
href="https://aur.archlinux.org/packages/alacritty-ligatures/">aur</a></p>
<figure>
<img src="alacritty.jpeg"
alt="screenshot of the terminal showing alacritty ligatures" />
<figcaption aria-hidden="true">screenshot of the terminal showing
alacritty ligatures</figcaption>
</figure>
<hr />
<h2 id="starship">Starship</h2>
<p>I used to use zsh + powerlevel9k as my prompt and even when I migrate
to powerlevel10k, I still notice a delay when open new shell. But with
starship it’s start instantly.</p>
<p>You can use it with any shell bash, zsh, fish and even
powerShell.</p>
<p>The screenshot below showing the result of my customized
configuration.</p>
<figure>
<img src="starship.jpeg" alt="screenshot of starship prompt" />
<figcaption aria-hidden="true">screenshot of starship
prompt</figcaption>
</figure>
<hr />
<h2 id="exa">Exa</h2>
<p>exa is an implementation of <code>ls</code> command but with colors
and icons and it renders very fast.</p>
<p>I’m using exa as replacer for ls command by making an alias.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="bu">[</span> <span class="st">&quot;</span><span class="va">$(</span><span class="bu">command</span> <span class="at">-v</span> exa<span class="va">)</span><span class="st">&quot;</span> <span class="bu">]</span><span class="kw">;</span> <span class="cf">then</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">unalias</span> <span class="at">-m</span> <span class="st">&#39;ll&#39;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="bu">unalias</span> <span class="at">-m</span> <span class="st">&#39;l&#39;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="bu">unalias</span> <span class="at">-m</span> <span class="st">&#39;la&#39;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="bu">unalias</span> <span class="at">-m</span> <span class="st">&#39;ls&#39;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="bu">alias</span> ls=<span class="st">&#39;exa -G  --color auto --icons -a -s type&#39;</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="bu">alias</span> ll=<span class="st">&#39;exa -l --color always --icons -a -s type&#39;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span></code></pre></div>
<p>the result of my <code>ls</code> and <code>ll</code> commands.</p>
<figure>
<img src="exa.jpeg" alt="screenshot of exa" />
<figcaption aria-hidden="true">screenshot of exa</figcaption>
</figure>
<hr />
<h2 id="bat">Bat</h2>
<p>Bat is an implementation for <code>cat</code> command but with syntax
highlighted.</p>
<p>Also I make an alias for this command with nord theme.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="bu">[</span> <span class="st">&quot;</span><span class="va">$(</span><span class="bu">command</span> <span class="at">-v</span> bat<span class="va">)</span><span class="st">&quot;</span> <span class="bu">]</span><span class="kw">;</span> <span class="cf">then</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="bu">unalias</span> <span class="at">-m</span> <span class="st">&#39;cat&#39;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="bu">alias</span> cat=<span class="st">&#39;bat -pp --theme=&quot;Nord&quot;&#39;</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="cf">fi</span></span></code></pre></div>
<figure>
<img src="bat.jpeg" alt="screenshot of bat" />
<figcaption aria-hidden="true">screenshot of bat</figcaption>
</figure>
<hr />
<h2 id="delta">Delta</h2>
<p>delta enhance your git diff output by adding some cool features like
syntax highlighting, line numbering, and side-by-side view.</p>
<p>to make delta works in your <code>.gitconfig</code> file add:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">[</span><span class="at">core</span><span class="kw">]</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="at">  pager = delta</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">[</span><span class="at">interactive</span><span class="kw">]</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="at">  diffFilter = delta --color-only</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">[</span><span class="at">delta</span><span class="kw">]</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="at">  side-by-side = true</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="at">  line-numbers-left-format = &quot;&quot;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="at">  line-numbers-right-format = &quot;│ &quot;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="at">  syntax-theme = Nord</span></span></code></pre></div>
<p>we set <code>delta</code> as the default pager for git commands
output and enable side-by-side feature and set a theme for Nord, You can
choose your preferred theme run and choose one.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">delta</span> <span class="at">--list-syntax-themes</span></span></code></pre></div>
<figure>
<img src="delta.jpeg" alt="screenshot of delta" />
<figcaption aria-hidden="true">screenshot of delta</figcaption>
</figure>
<hr />
<h2 id="zoxide">Zoxide</h2>
<p>I don’t use any file explorer, I just use <code>cd</code> command to
navigate between the files and <code>ls</code> commands.</p>
<p>I have a <code>projects</code> directory on my home folder if I wanna
navigate to a project of those projects. I will write</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> ~/projects/mahmoudashraf.dev</span></code></pre></div>
<p>instead I will write</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">z</span> ~/projects/mahmoudashraf.dev</span></code></pre></div>
<p>just to the first time and if I wanna navigate again to this
directory from anywhere just write</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">z</span> mah</span></code></pre></div>
<hr />
<h2 id="ripgrep">Ripgrep</h2>
<p>It is a cross-platform command line searches your directory for a
regex pattern.</p>
<p>I recommend you read this article <a
href="https://blog.burntsushi.net/ripgrep/">ripgrep is faster than
{grep, ag, git grep, ucg, pt, sift}</a>.</p>
<p>some commands that i’m using</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># search on javascript files for specific regex</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="ex">rg</span> tjs <span class="st">&quot;import React&quot;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="ex">rg</span> <span class="st">&quot;\.content&quot;</span> <span class="at">-g</span> <span class="st">&quot;*.pug&quot;</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="co"># you can also search and replace with regex as sed command</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="ex">rg</span> fast README.md <span class="at">--replace</span> FAST</span></code></pre></div>
<figure>
<img src="ripgrep.jpeg" alt="screenshot of ripgrep" />
<figcaption aria-hidden="true">screenshot of ripgrep</figcaption>
</figure>
<hr />
<h2 id="fd">Fd</h2>
<p>the friendly version of <code>find</code> command, and faster.</p>
<p>It’s by default ignore <code>.gitignore</code> file</p>
<p>in this tutorial I have some screenshots in <code>png</code> format
to convert them all to <code>jpeg</code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">fd</span> <span class="at">-e</span> png <span class="at">-x</span> convert {} {.}.jpeg</span></code></pre></div>
<p>To delete files</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">fd</span> <span class="at">-H</span> <span class="st">&#39;^\.DS_Store$&#39;</span> <span class="at">-tf</span> <span class="at">-X</span> rm</span></code></pre></div>
<hr />
<h2 id="bottom">bottom</h2>
<p>In this time not <code>top</code> 😀 it is <code>bottom</code></p>
<p>it’s a cross-platform system monitor.</p>
<figure>
<img src="bottom.jpeg" alt="screenshot of bottom" />
<figcaption aria-hidden="true">screenshot of bottom</figcaption>
</figure>
<hr />
<h2 id="tldr-1">Tldr</h2>
<p>tldr is a cheatsheets for CLIs, instead of read the whole
<code>man</code>.</p>
<figure>
<img src="tldr.jpeg" alt="screenshot of tldr" />
<figcaption aria-hidden="true">screenshot of tldr</figcaption>
</figure>
<hr />
<h2 id="more-tools">More Tools?</h2>
<ul>
<li>for who want lightweight alternative for spotify client you can use
<code>spotify-tui</code>.</li>
<li>also if you prefer an UI interface for git check
<code>gitui</code>.</li>
</ul>
<p>and there is a ton of CLIs and tools written in rust you can check <a
href="https://lib.rs/command-line-utilities">lib.rs/command-line-utilities</a></p>
]]></content:encoded>
</item>
<item>
<title>Building a blog with Svelte, Sapper, and Markdown</title>
<guid>https://maw.sh/blog/build-a-blog-with-svelte-and-markdown</guid>
<link>https://maw.sh/blog/build-a-blog-with-svelte-and-markdown</link>
<pubDate>Tue, 03 Mar 2020 00:00:00 +0000</pubDate>
<description>In this article I will show how you can start bloging with svelte and sapper using markdown files</description>
<content:encoded><![CDATA[
<h1 id="building-a-blog-with-svelte-sapper-and-markdown">Building a blog
with Svelte, Sapper, and Markdown</h1>
<p>In this post, we will build a website with a blog using svelte, and
sapper.</p>
<h2 id="what-is-svelte">What is Svelte?</h2>
<p>Svelte is a new javascript framework come on the table, Svelte has a
philosophy that helps you manipulate the DOM without using any
additional techniques like virtual DOM, Svelte compile your code on the
build time, and you can update your app easily using reactivity.</p>
<h2 id="what-is-sapper">What is Sapper?</h2>
<p>Sapper is a Server Side framework on top of Svelte helps you create
PWA apps with a good SEO and file system based routing.</p>
<h2 id="how-to-init-the-project">How to init the project?</h2>
<p>We are going to use the starter template provided by the Sapper team,
open your favorite terminal and write the following command:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>  <span class="ex">npx</span> degit <span class="st">&quot;sveltejs/sapper-template#rollup&quot;</span> cool-blog</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="bu">cd</span> /cool-blog</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="ex">npm</span> install</span></code></pre></div>
<p>After installing the dependencies, you should be good to go and start
your server.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>  <span class="ex">npm</span> run dev</span></code></pre></div>
<p>Voila, 🎉 the application now up and running.</p>
<figure>
<img src="bg1.jpeg"
alt="screenshot of the home page for sapper boilerplate" />
<figcaption aria-hidden="true">screenshot of the home page for sapper
boilerplate</figcaption>
</figure>
<p>Let’s open the project in your favorite editor. and go to the
<code>blog</code> folder inside the <code>src/routes</code>.</p>
<p>We have several files there:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">|</span> <span class="ex">src</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">|</span> <span class="ex">routes</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>      <span class="kw">|</span> <span class="ex">blog</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        <span class="ex">-</span> index.svelte,</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="ex">-</span> index.json.js</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="ex">-</span> [slug].svelte</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        <span class="ex">-</span> [slug].json.js</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        <span class="ex">-</span> _posts.js</span></code></pre></div>
<h2 id="how-routing-works-in-sapper">How routing works in sapper?</h2>
<p>we have two types the pages, and server routes.</p>
<h3 id="pages">Pages</h3>
<p>The filename detrmine the route. For example:
<code>src/routes/blog/index.svelte</code> refer to the route
<code>/blog</code>.</p>
<p>For Dynamin routing. we going to use <code>[slug]</code>. For example
<code>ser/routes/blog/[slug].svelte</code> refer to route
<code>/blog/the-whatever-blog-name</code></p>
<h3 id="server">Server</h3>
<p>Server routes are modules written in <code>.js</code> files that
export HTTP functions. For example <code>get</code> endpoint to retrieve
the blog details:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">// [slug].json.js</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> posts <span class="im">from</span> <span class="st">&#39;./_posts.js&#39;</span><span class="op">;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> lookup <span class="op">=</span> <span class="kw">new</span> <span class="bu">Map</span>()<span class="op">;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>posts<span class="op">.</span><span class="fu">forEach</span>((post) <span class="kw">=&gt;</span> {</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  lookup<span class="op">.</span><span class="fu">set</span>(post<span class="op">.</span><span class="at">slug</span><span class="op">,</span> <span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>(post))<span class="op">;</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>})<span class="op">;</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">function</span> <span class="fu">get</span>(req<span class="op">,</span> res<span class="op">,</span> next) {</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  <span class="co">// the `slug` parameter is available because</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  <span class="co">// this file is called [slug].json.js</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> { slug } <span class="op">=</span> req<span class="op">.</span><span class="at">params</span><span class="op">;</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (lookup<span class="op">.</span><span class="fu">has</span>(slug)) {</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    res<span class="op">.</span><span class="fu">writeHead</span>(<span class="dv">200</span><span class="op">,</span> {</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>      <span class="st">&#39;Content-Type&#39;</span><span class="op">:</span> <span class="st">&#39;application/json&#39;</span><span class="op">,</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    })<span class="op">;</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>    res<span class="op">.</span><span class="fu">end</span>(lookup<span class="op">.</span><span class="fu">get</span>(slug))<span class="op">;</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>  } <span class="cf">else</span> {</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>    res<span class="op">.</span><span class="fu">writeHead</span>(<span class="dv">404</span><span class="op">,</span> {</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>      <span class="st">&#39;Content-Type&#39;</span><span class="op">:</span> <span class="st">&#39;application/json&#39;</span><span class="op">,</span></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>    })<span class="op">;</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a>    res<span class="op">.</span><span class="fu">end</span>(</span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>      <span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>({</span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>        <span class="dt">message</span><span class="op">:</span> <span class="vs">`Not found`</span><span class="op">,</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>      })<span class="op">,</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a>    )<span class="op">;</span></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Create a <code>content</code> directory on the root of your project.
inside this directory, we going to create a file called
<code>sample-post.md</code> file.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode markdown"><code class="sourceCode markdown"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>// sample-blog.md</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>// remove comments in case you copy and paste this file for test to make it work</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>---</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>slug: &#39;sample-blog&#39;</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>title: &#39;Sample blog.&#39;</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>---</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="fu"># Sample title</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>this is a sample blog post.</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>// add extra <span class="sc">\`</span> to make it work(this blog use same method so tripple <span class="sc">\`</span> would be shown as a code here)</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>`javascript</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>  console.log(&quot;test code highlight&quot;)</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>`</span></code></pre></div>
<p><code>slug</code> has to be the same as the file name, So we can
easily read the file with the slug. You can add more than
<code>title</code>, and <code>slug</code>, For Example, Date, keywords
or whatever you need to add.</p>
<p>To list all blogs on <code>/blog</code> route open
<code>src/routes/blog/index.json.js</code></p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">// src/routes/blog/index.json.js</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> fs <span class="im">from</span> <span class="st">&#39;fs&#39;</span><span class="op">;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> path <span class="im">from</span> <span class="st">&#39;path&#39;</span><span class="op">;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> grayMatter <span class="im">from</span> <span class="st">&#39;gray-matter&#39;</span><span class="op">;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> getAllPosts <span class="op">=</span> () <span class="kw">=&gt;</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  fs<span class="op">.</span><span class="fu">readdirSync</span>(<span class="st">&#39;content&#39;</span>)<span class="op">.</span><span class="fu">map</span>((fileName) <span class="kw">=&gt;</span> {</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> post <span class="op">=</span> fs<span class="op">.</span><span class="fu">readFileSync</span>(path<span class="op">.</span><span class="fu">resolve</span>(<span class="st">&#39;content&#39;</span><span class="op">,</span> fileName)<span class="op">,</span> <span class="st">&#39;utf-8&#39;</span>)<span class="op">;</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">grayMatter</span>(post)<span class="op">.</span><span class="at">data</span><span class="op">;</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  })<span class="op">;</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">function</span> <span class="fu">get</span>(req<span class="op">,</span> res) {</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>  res<span class="op">.</span><span class="fu">writeHead</span>(<span class="dv">200</span><span class="op">,</span> {</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;Content-Type&#39;</span><span class="op">:</span> <span class="st">&#39;application/json&#39;</span><span class="op">,</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>  })<span class="op">;</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> posts <span class="op">=</span> <span class="fu">getAllPosts</span>()<span class="op">;</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>  res<span class="op">.</span><span class="fu">end</span>(<span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>(posts))<span class="op">;</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>You need to install an extra package called <code>gray-matter</code>
that helps you parse the front matter data <code>title</code>, and
<code>slug</code> from the markdown.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>  <span class="ex">npm</span> install gray-matter</span></code></pre></div>
<p>If you navigate to <code>/blog</code> route you should have a page
similar to this:</p>
<figure>
<img src="bg2.jpeg" alt="screenshot of blogs pages" />
<figcaption aria-hidden="true">screenshot of blogs pages</figcaption>
</figure>
<p>Now we need to handle the post route. open
<code>src/routes/blog/[slug].json.js</code></p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>  <span class="co">// src/routes/blog/[slug].json.js</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> path <span class="im">from</span> <span class="st">&quot;path&quot;</span><span class="op">;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> fs <span class="im">from</span> <span class="st">&quot;fs&quot;</span><span class="op">;</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> grayMatter <span class="im">from</span> <span class="st">&quot;gray-matter&quot;</span><span class="op">;</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> marked <span class="im">from</span> <span class="st">&quot;marked&quot;</span><span class="op">;</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> hljs <span class="im">from</span> <span class="st">&quot;highlight.js&quot;</span><span class="op">;</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> getPost <span class="op">=</span> fileName <span class="kw">=&gt;</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    fs<span class="op">.</span><span class="fu">readFileSync</span>(path<span class="op">.</span><span class="fu">resolve</span>(<span class="st">&quot;content&quot;</span><span class="op">,</span> <span class="vs">`</span><span class="sc">${</span>fileName<span class="sc">}</span><span class="vs">.md`</span>)<span class="op">,</span> <span class="st">&quot;utf-8&quot;</span>)<span class="op">;</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>  <span class="im">export</span> <span class="kw">function</span> <span class="fu">get</span>(req<span class="op">,</span> res<span class="op">,</span> next) {</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> { slug } <span class="op">=</span> req<span class="op">.</span><span class="at">params</span><span class="op">;</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// get the markdown text</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> post <span class="op">=</span> <span class="fu">getPost</span>(slug)<span class="op">;</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>    <span class="co">// function that expose helpful callbacks</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>    <span class="co">// to manipulate the data before convert it into html</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> renderer <span class="op">=</span> <span class="kw">new</span> marked<span class="op">.</span><span class="fu">Renderer</span>()<span class="op">;</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a><span class="op">./</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// use hljs to highlight our blocks codes</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>    renderer<span class="op">.</span><span class="at">code</span> <span class="op">=</span> (source<span class="op">,</span> lang) <span class="kw">=&gt;</span> {</span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> { <span class="dt">value</span><span class="op">:</span> highlighted } <span class="op">=</span> hljs<span class="op">.</span><span class="fu">highlight</span>(lang<span class="op">,</span> source)<span class="op">;</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="vs">`&lt;pre class=&#39;language-javascriptreact&#39;&gt;&lt;code&gt;</span><span class="sc">${</span>highlighted<span class="sc">}</span><span class="vs">&lt;/code&gt;&lt;/pre&gt;`</span><span class="op">;</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>    }<span class="op">;</span></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>    <span class="co">// parse the md to get front matter</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>    <span class="co">// and the content without escaping characters</span></span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> { data<span class="op">,</span> content } <span class="op">=</span> <span class="fu">grayMatter</span>(post)<span class="op">;</span></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> html <span class="op">=</span> <span class="fu">marked</span>(content<span class="op">,</span> { renderer })<span class="op">;</span></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (html) {</span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a>      res<span class="op">.</span><span class="fu">writeHead</span>(<span class="dv">200</span><span class="op">,</span> {</span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;Content-Type&quot;</span><span class="op">:</span> <span class="st">&quot;application/json&quot;</span></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a>      })<span class="op">;</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a>      res<span class="op">.</span><span class="fu">end</span>(<span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>({ html<span class="op">,</span> <span class="op">...</span>data }))<span class="op">;</span></span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a>    } <span class="cf">else</span> {</span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a>      res<span class="op">.</span><span class="fu">writeHead</span>(<span class="dv">404</span><span class="op">,</span> {</span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;Content-Type&quot;</span><span class="op">:</span> <span class="st">&quot;application/json&quot;</span></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a>      })<span class="op">;</span></span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true" tabindex="-1"></a>      res<span class="op">.</span><span class="fu">end</span>(</span>
<span id="cb8-46"><a href="#cb8-46" aria-hidden="true" tabindex="-1"></a>        <span class="bu">JSON</span><span class="op">.</span><span class="fu">stringify</span>({</span>
<span id="cb8-47"><a href="#cb8-47" aria-hidden="true" tabindex="-1"></a>          <span class="dt">message</span><span class="op">:</span> <span class="vs">`Not found`</span></span>
<span id="cb8-48"><a href="#cb8-48" aria-hidden="true" tabindex="-1"></a>        })</span>
<span id="cb8-49"><a href="#cb8-49" aria-hidden="true" tabindex="-1"></a>      )<span class="op">;</span></span>
<span id="cb8-50"><a href="#cb8-50" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb8-51"><a href="#cb8-51" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>Two new packages we need to install</p>
<ul>
<li>marked: help us to convert the markdown file into HTML.</li>
<li>highlight.js: add highlights to the code blocks.</li>
</ul>
<div class="sourceCode" id="cb9"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>  <span class="ex">npm</span> install highlight.js marked</span></code></pre></div>
<p>In <code>src/client.js</code> we import Github styles for
highlight.js.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co">// src/client.js</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> <span class="st">&#39;highlight.js/styles/github.css&#39;</span><span class="op">;</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span></code></pre></div>
<figure>
<img src="bg3.jpeg"
alt="screenshot of the final result showing a sample blog post" />
<figcaption aria-hidden="true">screenshot of the final result showing a
sample blog post</figcaption>
</figure>
<h2 id="conclusion">conclusion</h2>
<p>You now ready to go and add more styles for your website and
customize the blog elements styles. to go live using <a
href="http://netlify.com/">Netlify</a>, <a
href="https://pages.github.com/">Github Page</a> or any service.</p>
]]></content:encoded>
</item>
<item>
<title>How to optimize and lazy-loading images on eleventy (11ty)</title>
<guid>https://maw.sh/blog/how-to-optimize-and-lazyloading-images-on-eleventy</guid>
<link>https://maw.sh/blog/how-to-optimize-and-lazyloading-images-on-eleventy</link>
<pubDate>Tue, 01 Sep 2020 00:00:00 +0000</pubDate>
<description>Learn How to automate your images using eleventy-img plugin and sharpjs</description>
<content:encoded><![CDATA[
<h1 id="how-to-optimize-and-lazy-loading-images-on-eleventy-11ty">How to
optimize and lazy-loading images on eleventy (11ty)</h1>
<p>Building a site that has images requires to optimize them to avoid
any content shifting and deliver a good user experience.</p>
<p>To achieve that you have to compress, resize, and convert formats for
your images.</p>
<p>In this article we will take a look for how to automate your images
in eleventy static site generated website using <a
href="https://github.com/11ty/eleventy-img/">eleventy-img</a>, and <a
href="https://github.com/lovell/sharp">sharp</a>.</p>
<h2 id="create-a-basic-project-to-start">Create a basic project to
start</h2>
<p>create a new directory and name it <code>11ty-img-example</code> or
whatever you want, then run</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">yarn</span> init <span class="at">-y</span></span></code></pre></div>
<p>you can use <code>npm</code> if you prefer.</p>
<p>now install <code>eleventy</code>, and create index.njk on the root
with basic <code>html</code> markup.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">yarn</span> add <span class="at">-D</span> @11ty/eleventy</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">touch</span> index.njk</span></code></pre></div>
<div class="sourceCode" id="cb3"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- index.njk --&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;html</span> <span class="er">lang</span><span class="ot">=</span><span class="st">&quot;en&quot;</span><span class="kw">&gt;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;head&gt;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">&lt;meta</span> <span class="er">charset</span><span class="ot">=</span><span class="st">&quot;UTF-8&quot;</span> <span class="kw">/&gt;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">&lt;meta</span> <span class="er">name</span><span class="ot">=</span><span class="st">&quot;viewport&quot;</span> <span class="er">content</span><span class="ot">=</span><span class="st">&quot;width=device-width, initial-scale=1.0&quot;</span> <span class="kw">/&gt;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">&lt;title&gt;</span>11ty img example<span class="kw">&lt;/title&gt;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;/head&gt;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;body&gt;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    Hello, World!</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;/body&gt;</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>open your <code>package.json</code> file and add dev and build
scripts:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="er">//</span> <span class="er">package.json</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="er">&quot;scripts&quot;:</span> <span class="fu">{</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&quot;dev&quot;</span><span class="fu">:</span> <span class="st">&quot;eleventy --serve&quot;</span><span class="fu">,</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&quot;build&quot;</span><span class="fu">:</span> <span class="st">&quot;eleventy&quot;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h2 id="run-the-project-on-your-browser">run the project on your
browser</h2>
<p>open your favorite terminal and run</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">yarn</span> dev</span></code></pre></div>
<p>now open <code>localhost:8080</code> on your browser and it should
work without any customized eleventy configuration.</p>
<figure>
<img src="setup-screen.jpeg"
alt="screenshot of application inside the browser" />
<figcaption aria-hidden="true">screenshot of application inside the
browser</figcaption>
</figure>
<h2 id="display-some-images">Display some images</h2>
<p>let’s try get some images and place them in <code>images</code>
directory. and inside <code>index.njk</code> try to display theme.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ls</span> images/</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ex">518k</span>   0001.jpeg</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ex">2.6M</span>   0002.jpeg</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ex">1.7M</span>   0003.jpeg</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="ex">368k</span>   0004.jpeg</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="ex">679k</span>   0005.jpeg</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="ex">556k</span>   0006.jpeg</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="ex">602k</span>   0007.jpeg</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="ex">1.6M</span>   0008.jpeg</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="ex">1.4M</span>   0009.jpeg</span></code></pre></div>
<div class="sourceCode" id="cb7"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- index.njk --&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;img</span> <span class="er">src</span><span class="ot">=</span><span class="st">&quot;/images/0001.jpeg&quot;</span> <span class="er">alt</span><span class="ot">=</span><span class="st">&quot;image no 01&quot;</span> <span class="kw">/&gt;</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">&lt;img</span> <span class="er">src</span><span class="ot">=</span><span class="st">&quot;/images/0002.jpeg&quot;</span> <span class="er">alt</span><span class="ot">=</span><span class="st">&quot;image no 02&quot;</span> <span class="kw">/&gt;</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">&lt;!-- ... --&gt;</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;/body&gt;</span></span></code></pre></div>
<p>open your browser and it shouldn’t render any image. yeah that’s
right 😀 because <code>eleventy</code> doesn’t handle assets like css,
js, or images so we need to configure that by ourself.</p>
<p>create a <code>.eleventy.js</code> file on the root directory, then
write:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>module<span class="op">.</span><span class="at">exports</span> <span class="op">=</span> (cfg) <span class="kw">=&gt;</span> {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  cfg<span class="op">.</span><span class="fu">addPassthroughCopy</span>(<span class="st">&#39;images&#39;</span>)<span class="op">;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>now everything inside <code>images</code> directory will be copied to
the build directory.</p>
<p>Restart your server and go back to your browser and it should
everything work.</p>
<figure>
<img src="images-screen.jpeg"
alt="screenshot of application inside the browser" />
<figcaption aria-hidden="true">screenshot of application inside the
browser</figcaption>
</figure>
<h2 id="test-images-performance-without-optimization">Test images
performance without optimization</h2>
<p>Let’s see how images doing before any optimization.</p>
<p>Open network tab inside the devtool and set <code>fast 3G</code> as
network simulation.</p>
<p>in my case it took <code>50s</code> to render all images, and some of
these images have size more than <code>2mb</code>. so we need to find a
way to make it faster.</p>
<figure>
<img src="network-vid.gif"
alt="gif showing how slow the image rendering" />
<figcaption aria-hidden="true">gif showing how slow the image
rendering</figcaption>
</figure>
<h2 id="add-eleventy-img-plugin">Add <code>eleventy-img</code>
plugin</h2>
<p>it’s the time to use the <code>eleventy-img</code>, this plugin from
eleventy team you can find the repo from <a
href="https://github.com/11ty/eleventy-img/">here</a>.</p>
<p>Install it in our project.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">yarn</span> add <span class="at">-D</span> @11ty/eleventy-img</span></code></pre></div>
<p>open <code>.eleventy.js</code> file and remove the line that we wrote
before, then add the code below:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode js"><code class="sourceCode javascript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co">// .eleventy.js</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Image <span class="op">=</span> <span class="pp">require</span>(<span class="st">&#39;@11ty/eleventy-img&#39;</span>)<span class="op">;</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>module<span class="op">.</span><span class="at">exports</span> <span class="op">=</span> (cfg) <span class="kw">=&gt;</span> {</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  cfg<span class="op">.</span><span class="fu">addNunjucksAsyncShortcode</span>(<span class="st">&#39;Image&#39;</span><span class="op">,</span> <span class="kw">async</span> (src<span class="op">,</span> alt) <span class="kw">=&gt;</span> {</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="op">!</span>alt) {</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">throw</span> <span class="kw">new</span> <span class="bu">Error</span>(<span class="vs">`Missing </span><span class="sc">\`</span><span class="vs">alt</span><span class="sc">\`</span><span class="vs"> on myImage from: </span><span class="sc">${</span>src<span class="sc">}</span><span class="vs">`</span>)<span class="op">;</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> stats <span class="op">=</span> <span class="cf">await</span> <span class="fu">Image</span>(src<span class="op">,</span> {</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>      <span class="dt">widths</span><span class="op">:</span> [<span class="dv">25</span><span class="op">,</span> <span class="dv">320</span><span class="op">,</span> <span class="dv">640</span><span class="op">,</span> <span class="dv">960</span><span class="op">,</span> <span class="dv">1200</span><span class="op">,</span> <span class="dv">1800</span><span class="op">,</span> <span class="dv">2400</span>]<span class="op">,</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>      <span class="dt">formats</span><span class="op">:</span> [<span class="st">&#39;jpeg&#39;</span><span class="op">,</span> <span class="st">&#39;webp&#39;</span>]<span class="op">,</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>      <span class="dt">urlPath</span><span class="op">:</span> <span class="st">&#39;/images/&#39;</span><span class="op">,</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>      <span class="dt">outputDir</span><span class="op">:</span> <span class="st">&#39;./_site/images/&#39;</span><span class="op">,</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>    })<span class="op">;</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> lowestSrc <span class="op">=</span> stats[<span class="st">&#39;jpeg&#39;</span>][<span class="dv">0</span>]<span class="op">;</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> srcset <span class="op">=</span> <span class="bu">Object</span><span class="op">.</span><span class="fu">keys</span>(stats)<span class="op">.</span><span class="fu">reduce</span>(</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>      (acc<span class="op">,</span> format) <span class="kw">=&gt;</span> ({</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">...</span>acc<span class="op">,</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>        [format]<span class="op">:</span> stats[format]<span class="op">.</span><span class="fu">reduce</span>(</span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>          (_acc<span class="op">,</span> curr) <span class="kw">=&gt;</span> <span class="vs">`</span><span class="sc">${</span>_acc<span class="sc">}</span><span class="vs"> </span><span class="sc">${</span>curr<span class="op">.</span><span class="at">srcset</span><span class="sc">}</span><span class="vs"> ,`</span><span class="op">,</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>          <span class="st">&#39;&#39;</span><span class="op">,</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>        )<span class="op">,</span></span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a>      })<span class="op">,</span></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a>      {}<span class="op">,</span></span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>    )<span class="op">;</span></span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> source <span class="op">=</span> <span class="vs">`&lt;source type=&quot;image/webp&quot; srcset=&quot;</span><span class="sc">${</span>srcset[<span class="st">&#39;webp&#39;</span>]<span class="sc">}</span><span class="vs">&quot; &gt;`</span><span class="op">;</span></span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> img <span class="op">=</span> <span class="vs">`&lt;img</span></span>
<span id="cb10-34"><a href="#cb10-34" aria-hidden="true" tabindex="-1"></a><span class="vs">      loading=&quot;lazy&quot;</span></span>
<span id="cb10-35"><a href="#cb10-35" aria-hidden="true" tabindex="-1"></a><span class="vs">      alt=&quot;</span><span class="sc">${</span>alt<span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb10-36"><a href="#cb10-36" aria-hidden="true" tabindex="-1"></a><span class="vs">      src=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">url</span><span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb10-37"><a href="#cb10-37" aria-hidden="true" tabindex="-1"></a><span class="vs">      sizes=&#39;(min-width: 1024px) 1024px, 100vw&#39;</span></span>
<span id="cb10-38"><a href="#cb10-38" aria-hidden="true" tabindex="-1"></a><span class="vs">      srcset=&quot;</span><span class="sc">${</span>srcset[<span class="st">&#39;jpeg&#39;</span>]<span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb10-39"><a href="#cb10-39" aria-hidden="true" tabindex="-1"></a><span class="vs">      width=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">width</span><span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb10-40"><a href="#cb10-40" aria-hidden="true" tabindex="-1"></a><span class="vs">      height=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">height</span><span class="sc">}</span><span class="vs">&quot;&gt;`</span><span class="op">;</span></span>
<span id="cb10-41"><a href="#cb10-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-42"><a href="#cb10-42" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="vs">`&lt;div class=&quot;image-wrapper&quot;&gt;&lt;picture&gt; </span><span class="sc">${</span>source<span class="sc">}</span><span class="vs"> </span><span class="sc">${</span>img<span class="sc">}</span><span class="vs"> &lt;/picture&gt;&lt;/div&gt;`</span><span class="op">;</span></span>
<span id="cb10-43"><a href="#cb10-43" aria-hidden="true" tabindex="-1"></a>  })<span class="op">;</span></span>
<span id="cb10-44"><a href="#cb10-44" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>Let’s break down the code and understand how it works</p>
<ul>
<li><code>addNunjucksAsyncShortcode</code></li>
</ul>
<p>eleventy has feature called <code>shortcodes</code> let you extend
your template engine by writing custom functions.</p>
<p>in our case we will have a new shortcode we can use inside our
templates by writing:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>{% Image &quot;/images/00.jpeg&quot;, &quot;this is an alt description&quot; %}</span></code></pre></div>
<ul>
<li><code>stats = new Image(...)</code></li>
</ul>
<p>we pass the src url, formats, and various widths to the image
plugin.</p>
<p>So we well have multiple sizes, and formats for each image.</p>
<ul>
<li><code>const srcset = ...</code></li>
</ul>
<p>the <code>stats</code> result look like that</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode js"><code class="sourceCode javascript"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>stats <span class="op">=</span> {</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">jpeg</span><span class="op">:</span> [</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    {</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">url</span><span class="op">:</span> <span class="st">&#39;...&#39;</span><span class="op">,</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>      <span class="dt">src</span><span class="op">:</span> <span class="st">&#39;...&#39;</span><span class="op">,</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">srcset</span><span class="op">:</span> <span class="st">&#39;...&#39;</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  ]<span class="op">,</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">webp</span><span class="op">:</span> [</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>  ]</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>We need to covert every size srcset to only one srcset string by
using <code>reduce</code> function, So we can inject it in our code.</p>
<p>so the result of variable <code>srcset</code></p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode js"><code class="sourceCode javascript"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>srcset <span class="op">=</span> {</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">jpeg</span><span class="op">:</span> <span class="st">&#39;&lt;srcset&gt;&#39;</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">webp</span><span class="op">:</span> <span class="st">&#39;&lt;srcset&gt;&#39;</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<ul>
<li><code>const source = ...</code> and
<code>const img = ...</code></li>
</ul>
<p>Use <code>webp</code> format for <code>source</code> as main image
type and <code>jpeg</code> as fallback fro <code>img</code> tag.</p>
<p>Now we are good to go by return the whole <code>picture</code>.</p>
<h2 id="test-images-after-using-eleventy-img">Test Images after using
<code>eleventy-img</code></h2>
<p>open <code>index.njk</code> and replace all <code>img</code> tags
with</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- index.njk --&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- ... --&gt;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>{% Image &quot;images/0001.jpeg&quot;, &quot;image no 01&quot; %} {% Image &quot;images/0002.jpeg&quot;,</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>&quot;image no 02&quot; %} {% Image &quot;images/0003.jpeg&quot;, &quot;image no 03&quot; %} {% Image</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>&quot;images/0004.jpeg&quot;, &quot;image no 04&quot; %}</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- ... --&gt;</span></span></code></pre></div>
<blockquote>
<p><strong>PS:</strong> you have to write image paths include the full
path from the root of the project to make it works.</p>
</blockquote>
<p>Restart your server and go to the browser. and again open network
tab.</p>
<p>and Boom 💥 in this time all images loaded on <code>5s</code> and no
image has size more than <code>120kb</code>.</p>
<figure>
<img src="network2-vid.gif"
alt="gif showing how the result after using eleventy-img plugin" />
<figcaption aria-hidden="true">gif showing how the result after using
eleventy-img plugin</figcaption>
</figure>
<h2 id="add-lazy-loading-and-the-blurry-effect">Add lazy-loading and the
blurry effect</h2>
<p>this is an extra step to avoid content shifting by using inline
<code>base64</code> image as placeholder for images and use javascript
as fallback for browser that not supported yet the native lazyloading
with <a
href="https://github.com/verlok/vanilla-lazyload">vanilla-lazyload</a>.</p>
<p>install sharp package to get the blurry inline base64 image</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ex">yarn</span> add <span class="at">-D</span> sharp</span></code></pre></div>
<p>on <code>.eleventy.js</code> import sharp package and add this code
below:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode js"><code class="sourceCode javascript"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="co">// .eleventy.js</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> sharp <span class="op">=</span> <span class="pp">require</span>(<span class="st">&#39;sharp&#39;</span>)<span class="op">;</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> placeholder <span class="op">=</span> <span class="cf">await</span> <span class="fu">sharp</span>(lowestSrc<span class="op">.</span><span class="at">outputPath</span>)</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">resize</span>({ <span class="dt">fit</span><span class="op">:</span> sharp<span class="op">.</span><span class="at">fit</span><span class="op">.</span><span class="at">inside</span> })</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">blur</span>()</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">toBuffer</span>()<span class="op">;</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> base64Placeholder <span class="op">=</span> <span class="vs">`data:image/png;base64,</span><span class="sc">${</span>placeholder<span class="op">.</span><span class="fu">toString</span>(</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>  <span class="st">&#39;base64&#39;</span><span class="op">,</span></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>)<span class="sc">}</span><span class="vs">`</span><span class="op">;</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span></code></pre></div>
<p>And then replace <code>src</code>, <code>srcset</code>, and
<code>resize</code>, to <code>data-src</code>, <code>data-srcset</code>,
and <code>data-resize</code>.</p>
<p>And also add <code>src</code> attribute in <code>&lt;img&gt;</code>
tag to <code>src="${base64Placeholder}"</code>.</p>
<p>The final code after changes:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode js"><code class="sourceCode javascript"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> source <span class="op">=</span> <span class="vs">`&lt;source type=&quot;image/webp&quot; data-srcset=&quot;</span><span class="sc">${</span>srcset[<span class="st">&#39;webp&#39;</span>]<span class="sc">}</span><span class="vs">&quot; &gt;`</span><span class="op">;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> img <span class="op">=</span> <span class="vs">`&lt;img</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="vs">  class=&quot;lazy&quot;</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="vs">  alt=&quot;</span><span class="sc">${</span>alt<span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="vs">  src=&quot;</span><span class="sc">${</span>base64Placeholder<span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="vs">  data-src=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">url</span><span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a><span class="vs">  data-sizes=&#39;(min-width: 1024px) 1024px, 100vw&#39;</span></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="vs">  data-srcset=&quot;</span><span class="sc">${</span>srcset[<span class="st">&#39;jpeg&#39;</span>]<span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a><span class="vs">  width=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">width</span><span class="sc">}</span><span class="vs">&quot;</span></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a><span class="vs">  height=&quot;</span><span class="sc">${</span>lowestSrc<span class="op">.</span><span class="at">height</span><span class="sc">}</span><span class="vs">&quot;&gt;`</span><span class="op">;</span></span></code></pre></div>
<p>And as mentioned before in this article that eleventy only handles
html template engines, So we will use <code>script</code> tag of
<code>type="module"</code> to use <code>vanilla-lazyload</code>
package.</p>
<p>on <code>index.njk</code> before the end of body tag
<code>&lt;/body&gt;</code> add this script.</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;script</span><span class="ot"> type=</span><span class="st">&quot;module&quot;</span> <span class="er">async</span><span class="kw">&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="im">import</span> Lazyload <span class="im">from</span> <span class="st">&#39;https://cdn.skypack.dev/vanilla-lazyload&#39;</span><span class="op">;</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> lazyload <span class="op">=</span> <span class="kw">new</span> <span class="fu">Lazyload</span>()<span class="op">;</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;/script&gt;</span></span></code></pre></div>
<p>Add this styles for img tags</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode html"><code class="sourceCode html"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;style&gt;</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  img {</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">display</span>: <span class="dv">block</span><span class="op">;</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">width</span>: <span class="dv">100</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">max-width</span>: <span class="dv">100</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">height</span>: <span class="bu">auto</span><span class="op">;</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;/style&gt;</span></span></code></pre></div>
<h2 id="test-images-after-lazyloading">Test images after
lazyloading</h2>
<p>Voilà 🎉, now we have a nice looking and fast images on your
site.</p>
<figure>
<img src="network3-vid.gif"
alt="gif showing how the result after using vanilla-lazyload and blurry base64" />
<figcaption aria-hidden="true">gif showing how the result after using
vanilla-lazyload and blurry base64</figcaption>
</figure>
<h2 id="conclusion">Conclusion</h2>
<p>Now You know how to integrate <code>eleventy-img</code> plugin and
<code>vanilla-lazyload</code> package with your eleventy site if you
need to learn more about image optimization, I recommend check this <a
href="https://www.andreaverlicchi.eu/lazy-load-responsive-images-in-2020-srcset-sizes-picture-webp/">blog</a>
by the author of <code>vanilla-lazyload</code>.</p>
<p>You can find the complete example in this <a
href="https://github.com/22mahmoud/elventy-image-example">github
repo</a></p>
]]></content:encoded>
</item>
<item>
<title>No More postman just use cURL + vim = ❤</title>
<guid>https://maw.sh/blog/no-more-postman-just-curl-and-vim</guid>
<link>https://maw.sh/blog/no-more-postman-just-curl-and-vim</link>
<pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate>
<description>Well documented api and easy to use and share with your team with simple tools cURL + vim + git (optional)</description>
<content:encoded><![CDATA[
<h1 id="no-more-postman-just-use-curl-vim">No More postman just use cURL
+ vim = ❤</h1>
<p>Postman one of the most popular API client tool, for send and view
the response in the development environment. But since Postman is
proprietary software and there is a free + open sourced alternative so
I’ll go for something like insomnia, or postwoman.</p>
<p>But also I’ll go for CLI if exists and cURL is one of the easy to use
and fully featured tool and in this article I’ll show you how to setup a
well-documented api with cURL + vim + git.</p>
<h2 id="how-to-execute-cli-inside-your-vim-editor">How to execute CLI
inside your vim editor?</h2>
<p>vim is very powerful editor and you can execute an command line
inside it. go to command mode and insert <code>:! &lt;command&gt;</code>
and hit enter.</p>
<p>for example:</p>
<pre class="vim"><code>  :! ls</code></pre>
<p>will execute the <code>ls</code> command line and show the content in
pager.</p>
<figure>
<img src="screen.jpeg" alt="screenshot for ls command inside vim" />
<figcaption aria-hidden="true">screenshot for ls command inside
vim</figcaption>
</figure>
<h2 id="execute-the-content-of-the-current-file-as-cli.">Execute the
content of the current file as CLI.</h2>
<p>open an empty file inside your vim and write inside it
<code>echo Hello, World!</code> and save it, and then write
<code>:!sh %</code>.</p>
<p>The percent <code>%</code> is refer to the filename so if we run it
with normal bang <code>:! %</code> it will not work because it’s trying
run the file as executable file not the content inside.</p>
<p>so we pass <code>sh</code> before the <code>%</code> to run the
content inside the file via shell.</p>
<figure>
<img src="screen1.jpeg" alt="screenshot :!sh command inside vim" />
<figcaption aria-hidden="true">screenshot :!sh command inside
vim</figcaption>
</figure>
<h2 id="test-our-first-curl-command">Test our first cURL command</h2>
<p>for demonstrating we will gonna use <a
href="https://jsonplaceholder.typicode.com/">jsonplaceholder</a> as our
API to test</p>
<p>Now create a folder structure like below:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">└──</span> api</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="ex">└──</span> todos</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>        <span class="ex">├──</span> delete</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   └── todo.zsh</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>        <span class="ex">├──</span> get</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   ├── todo-by-user.sh</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   ├── todo.sh</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   └── todos.sh</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        <span class="ex">├──</span> patch</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   └── todo.sh</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="ex">├──</span> post</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>        <span class="ex">│</span>   └── todo.sh</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>        <span class="ex">└──</span> put</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>            <span class="ex">└──</span> todo.sh</span></code></pre></div>
<p><code>.sh</code> to get file highlighted.</p>
<p>let’s start with first and simple one
<code>api/posts/get/todos.sh</code>.</p>
<p>write in the file and save.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-s</span> <span class="at">-X</span> GET <span class="dt">\</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;https://jsonplaceholder.typicode.com/todos&#39;</span></span></code></pre></div>
<p>then as we done before run <code>:!sh %</code></p>
<figure>
<img src="screen2.jpeg" alt="screenshot of :!sh % result inside vim" />
<figcaption aria-hidden="true">screenshot of :!sh % result inside
vim</figcaption>
</figure>
<h1 id="make-the-result-more-handy.">Make the result More Handy.</h1>
<p>In most tools you will get a split view for the request itself and
the result.</p>
<p>open you vim config file and add</p>
<pre class="vim"><code>command Exec set splitright | vnew | set filetype=sh | read !sh #</code></pre>
<p>the command before will open the result in a new buffer in vertical
view.</p>
<p>if you prefer horizontal view you can change the command to</p>
<pre class="vim"><code>command Exec set splitbelow | new | set filetype=sh | read !sh #</code></pre>
<p>open again <code>api/posts/get/todos.sh</code> and in command mode
write <code>:Exec</code> that will execute the command inside the file
and open split view with the result.</p>
<figure>
<img src="screen3.jpeg" alt="screenshot of before vim command" />
<figcaption aria-hidden="true">screenshot of before vim
command</figcaption>
</figure>
<p>now you have vim buffer you can easily search and do whatever you do.
and to close the buffer you can use command <code>:bd!</code> or the
keyboard shortcut <code>shift + z + q</code>.</p>
<h2 id="is-curl-limited">Is cURL limited?</h2>
<p>The answer is <strong>NO</strong>. let’s see couple of example</p>
<ul>
<li>POST Request:</li>
</ul>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-s</span> <span class="at">-X</span> POST <span class="dt">\</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;https://jsonplaceholder.typicode.com/posts&#39;</span> <span class="dt">\</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="at">-H</span> <span class="st">&#39;Content-Type: application/json&#39;</span> <span class="dt">\</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="at">-d</span> <span class="st">&#39;{ &quot;title&quot;: &quot;fooBatch&quot;, &quot;completed&quot;: false, &quot;userId&quot;: 1 }&#39;</span> <span class="dt">\</span></span></code></pre></div>
<p>you can make post, get, put, .. or any http request by using
<code>-X &lt;REQUEST_TYPE&gt;</code> option.</p>
<p>To pass the body data use <code>-d, --data {json format&gt;}</code> ,
and if the data is large you can write it in <code>json</code> file and
pass it as <code>-d @todo.json</code></p>
<ul>
<li>GET Request with query params:</li>
</ul>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-s</span> <span class="at">-X</span> GET <span class="at">-G</span> <span class="dt">\</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;https://jsonplaceholder.typicode.com/todos&#39;</span> <span class="dt">\</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="at">-d</span> <span class="st">&#39;userId=1&#39;</span></span></code></pre></div>
<p>you can still use query params with <code>-d</code> but add an
additional <code>-G, --get</code> to pass it as query params</p>
<p>since this is not a cURL tutorial that’s will be enough and you can
learn more about advanced stuff like set header, cookie and more from
the internet.</p>
<h2 id="using-git">Using git?</h2>
<p>Of course, on our created directory run <code>git init</code> and
push for example to github.</p>
<p><a href="https://github.com/22mahmoud/vim-curl-demo">see this example
on github</a></p>
<h2 id="conclusion">Conclusion</h2>
<p>You can now write a well-documented api and share it with your team
via git all that done with simple and open-sourced tools and that’s not
limited to cURL you can write your own scripts and run it inside vim, or
pipe your cURL command for other tools to manipulate the output for
example <code>jq</code> so you can filter your output.</p>
]]></content:encoded>
</item>
</channel>
</rss>
