<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Amith Raravi on Medium]]></title>
        <description><![CDATA[Stories by Amith Raravi on Medium]]></description>
        <link>https://medium.com/@raravi?source=rss-984ca699f9eb------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*-zIrHEMsZt2cJv8z_t2f-g@2x.jpeg</url>
            <title>Stories by Amith Raravi on Medium</title>
            <link>https://medium.com/@raravi?source=rss-984ca699f9eb------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 10:42:05 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@raravi/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Gatsby and the ‘window’ variable]]></title>
            <link>https://medium.com/@raravi/gatsby-and-the-window-variable-352ed558a8c0?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/352ed558a8c0</guid>
            <category><![CDATA[gatsbyjs]]></category>
            <category><![CDATA[isotope]]></category>
            <category><![CDATA[website]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[server-side-rendering]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Sat, 25 Jan 2020 01:30:17 GMT</pubDate>
            <atom:updated>2020-01-25T01:30:17.224Z</atom:updated>
            <content:encoded><![CDATA[<p>Where did the ‘window’ go? And how can I get it back?!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*jmOLhVPRryDWX_VBpVqnPw.png" /></figure><p>If you have a Gatsby website, then you may have noticed the window is not defined error when you try to do gatsby build. Since there were quite a few queries regarding this, I thought of explaining the issue and how to fix it!</p><h3>The Issue</h3><p>Say you have a 3rd party JavaScript API on your site. When you’re developing the site using Gatsby, you won’t see any issues. Running gatsby develop will be successful. This makes you think that everything is fine. But when you try to build the static site using gatsby build, it will throw the window is not defined error.</p><blockquote><em>Why does </em><em>gatsby develop run fine, but </em><em>gatsby build throw an error for the same code?!</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/1*w0Wliz2QZT878pJ2891Odg.png" /></figure><h3>&#39;gatsby develop’ vs &#39;gatsby build&#39;</h3><p>During development, Gatsby will run the code in the browser where window is available. Everything runs fine and you are left feeling happy, but not for long though :(</p><p>During build, Gatsby compiles your code on the Server Side. i.e., Gatsby will compile your code using Webpack on the server, and hence window is not accessible. Webpack knows all the imported stuff that goes into your code during the build phase (remember the 3rd party API ?!), and when it can’t find window it stops the build process by throwing an error.</p><h3>The Fix!</h3><p>The fix is to hide the window variable from Gatsby by doing a check for its existence. And move the offending code to the ComponentDidMount() function.</p><p>If you are importing a 3rd party API into your React component, then you should move the import to the ComponentDidMount() as well.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e43ef8e1839ef5047e9b6b6f921f24cf/href">https://medium.com/media/e43ef8e1839ef5047e9b6b6f921f24cf/href</a></iframe><p>This should resolve the window is not defined error and you should be able to build your code successfully. If you need more information regarding this, check the Gatsby documentation on <a href="https://www.gatsbyjs.org/docs/debugging-html-builds/">Debugging HTML Builds</a>.</p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/tech/website-design-creating-the-layout-in-html/"><em>www.amithraravi.com</em></a><em> on January 24, 2020.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=352ed558a8c0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[reCaptcha v3: Do You Need It?]]></title>
            <link>https://medium.com/@raravi/recaptcha-v3-do-you-need-it-3fe6b5a8bf5c?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/3fe6b5a8bf5c</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[google-recaptcha]]></category>
            <category><![CDATA[risk]]></category>
            <category><![CDATA[recaptcha]]></category>
            <category><![CDATA[spam]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Wed, 09 Oct 2019 23:04:13 GMT</pubDate>
            <atom:updated>2019-10-09T23:04:13.828Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*AXf2fdidc5lUv3cY.jpg" /><figcaption>Photo by <a href="https://unsplash.com/@paucasals">Pau Casals</a> on <a href="https://unsplash.com/">Unsplash</a>.</figcaption></figure><p>Google introduced version 3 of its reCaptcha in late 2018, announcing the ‘adaptive risk analysis’ spam handler for websites. And the question on everyone’s mind was: Should I upgrade from version 2 to version 3?</p><p>I think that’s the wrong way to go about it. As it’s not an upgrade in the regular sense. Version 3 is a different way of doing spam protection, with the website owner having more control over deciding who they think is a spammer/bot and what to do about it. That’s what version 3 offers, the platform for deciding. The website owner will still have to implement the actual mechanism of handling spam.</p><p>If you want a fine-tuned way of looking at spam, study the realtime data and continuously calibrate your spam meter, then version 3 is what you want.</p><h3>A Simple Setup</h3><p>Implementing reCaptcha version 3 is quite easy. Just follow the below steps: Go to the <a href="https://www.google.com/recaptcha/intro/v3.html">reCaptcha</a> website, and get your site registered. You will get a Public/Private key.</p><p>Add the below line to your HTML file (frontend) where you need reCaptcha. Replace <strong>YOUR-PUBLIC-KEY</strong> with your public key from the previous step.</p><pre>&lt;script src=&quot;https://www.google.com/recaptcha/api.js?render=YOUR-PUBLIC-KEY&quot;&gt;&lt;/script&gt;</pre><p>If you are running reCaptcha against a form, then create a new hidden input in the form:</p><pre>&lt;input type=&quot;hidden&quot; id=&quot;comment-token&quot; name=&quot;token&quot; value=&quot;&quot; /&gt;</pre><p>Now, for a bit of javascript magic. You will usually have a submit function to send the form to the server, to be processed by a script. In the submit function, you have to run grecaptcha.execute to get the token from Google. Again, replace <strong>YOUR-PUBLIC-KEY</strong> with your public key. Once you get the token, it has to be sent to your server along with the form data. I’ll explain why in the next step.</p><pre>$(&quot;#comment-form&quot;).submit(<strong>function</strong>() {<br>    event.preventDefault();<br>    grecaptcha.ready(<strong>function</strong>() {<br>      grecaptcha<br>        .execute(&quot;YOUR-PUBLIC-KEY&quot;, {action: &quot;addcomment&quot;})<br>        .then(<strong>function</strong>(token) {<br>          $(&quot;#comment-token&quot;).attr(&quot;value&quot;, token);<br>          $.ajax({<br>            type: $(&quot;#comment-form&quot;).attr(&quot;method&quot;),<br>            url: $(&quot;#comment-form&quot;).attr(&quot;action&quot;),<br>            data: $(&quot;#comment-form&quot;).serialize(),<br>            contentType: &quot;application/x-www-form-urlencoded&quot;<br>          })<br>            .done(<strong>function</strong>() {<br>              $(&quot;#comment-form-submit&quot;).html(&quot;Submitted&quot;);<br>            })<br>            .fail(<strong>function</strong>(<em>/*err*/</em>) {<br>              $(&quot;#comment-form-submit&quot;).html(&quot;Submit Comment&quot;);<br>            });<br>        });<br>    });</pre><pre>    <strong>return</strong> <strong>false</strong>;<br>  });</pre><p>Don’t get overwhelmed by the above piece of code. It’s easy to understand once you break it down:</p><ol><li>The submit function is called once the user hits the send/submit button on the form.</li><li>We need to call grecaptcha.execute to get the token.</li><li>Save the token in a hidden input field on the form (it will be picked up automatically to be sent to the server!)</li><li>I send the form data (with the token) using an Ajax call. Any other way will also work, the form data will get sent.</li></ol><p>Now that you have received the form data on your server, the token sent has to be verified. This is done by sending the token to Google and checking the response (I have used a PHP script here). Don’t forget to replace <strong>YOUR-PRIVATE-KEY</strong> with your private key.</p><pre>        $token        <strong>=</strong> $_POST[&#39;token&#39;];<br>        $secretKey    <strong>=</strong> &#39;YOUR-PRIVATE-KEY&#39;;</pre><pre>        <em>// post request to server</em><br>        $recaptchaurl <strong>=</strong>  &#39;https://www.google.com/recaptcha/api/siteverify?secret=&#39; <strong>.</strong> urlencode($secretKey) <strong>.</strong> &#39;&amp;response=&#39; <strong>.</strong> urlencode($token);<br>        $response     <strong>=</strong> file_get_contents($recaptchaurl);<br>        $responseKeys <strong>=</strong> json_decode($response,<strong>true</strong>);<br>        <em>// end post request</em></pre><p>The response received will be in JSON format:</p><pre>{<br>  &quot;success&quot;: <strong>true|false</strong>,      <em>// whether this request was a valid reCAPTCHA token for your site</em><br>  &quot;score&quot;: number,            <em>// the score for this request (0.0 - 1.0)</em><br>  &quot;action&quot;: string,           <em>// the action name for this request (important to verify)</em><br>  &quot;challenge_ts&quot;: timestamp,  <em>// timestamp of the challenge load (ISO format yyyy-MM-dd&#39;T&#39;HH:mm:ssZZ)</em><br>  &quot;hostname&quot;: string,         <em>// the hostname of the site where the reCAPTCHA was solved</em><br>  &quot;error-codes&quot;: [...]        <em>// optional</em><br>}</pre><p>From the <a href="https://developers.google.com/recaptcha/docs/v3">Google reCaptcha v3</a> docs.</p><p>Once you have the response, there are several things to evaluate.</p><ul><li>The success parameter will tell you if the reCaptcha token is valid.</li><li>The score will tell you if it’s considered spam(0.0) or human(1.0). The score will not be 0.0 or 1.0 but in the range of 0.0 - 1.0 to indicate the probability of spam. Values towards 0.0 have a higher probability of being spam, while values towards 1.0 are considered more genuine.</li><li>The action parameter will tell you the action against which this request was performed. Always verify this to match with the action on your frontend where the token got generated!</li><li>The hostname will tell you where the request originated, this should be from your web server!</li><li>In case of errors, the error-codes will give you the relevant codes to check.</li></ul><p>The above parameters are meant to help you decide on the best course of action to take for each form submission. You can</p><ul><li>Set a threshold value for letting the user in.</li><li>Send the riskier ones to a manual submission process.</li><li>Ask the user to more authentication (two-factor, mobile, email, etc).</li><li>Use the reCaptcha score as input for you machine-learning algorithms to determine how to handle it.</li></ul><p>The <a href="https://www.google.com/recaptcha/admin">Google Admin Console</a> on the reCaptcha v3 site gives you great insights on the kind of traffic hitting your site, and which parts are being targeted by bots. Use this to better calibrate spam protection in realtime!</p><h3>Control vs Convenience</h3><p>The reason to use reCaptcha v3 will be about how much control of the decision-making process you want to take up. Do you need to handle it on your own? Or are you okay with Google deciding for you? And how much money and resources are you willing to spend on handling the process yourself?</p><p>Here, I’ve left out another key piece of the puzzle. And that is how much spam/bots hit your site, and how sophisticated are they?! For extremely determined attacks, you will need a greater level of control of the decision-making process.</p><p>So, make your choice by weighing all these!</p><p>The introductory blog post from the <a href="https://security.googleblog.com/2018/10/introducing-recaptcha-v3-new-way-to.html">Google Security Blog</a> had this simple overview of the reCaptcha v3, and I think it pretty much says it all:</p><blockquote><em>“reCAPTCHA v3 runs adaptive risk analysis in the background to alert you of suspicious traffic while letting your human users enjoy a frictionless experience on your site.”</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fe6b5a8bf5c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Greta Thunberg at the United Nations]]></title>
            <link>https://medium.com/@raravi/greta-thunberg-at-the-united-nations-4da99b284af2?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/4da99b284af2</guid>
            <category><![CDATA[greta-thunberg]]></category>
            <category><![CDATA[fridays-for-future]]></category>
            <category><![CDATA[speech]]></category>
            <category><![CDATA[united-nations]]></category>
            <category><![CDATA[climate-change]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Mon, 23 Sep 2019 23:12:33 GMT</pubDate>
            <atom:updated>2019-09-23T23:12:33.856Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1HKOxBvMJs3o2XiEjecT5Q@2x.jpeg" /></figure><p>“My message is that we’ll be watching you.</p><p>This is all wrong. I shouldn’t be up here. I should be back in school on the other side of the ocean. Yet you all come to us young people for hope. How dare you!</p><p>You have stolen my dreams and my childhood with your empty words. And yet I’m one of the lucky ones. People are suffering. People are dying. Entire ecosystems are collapsing. We are in the beginning of a mass extinction, and all you can talk about is money and fairy tales of eternal economic growth. How dare you!</p><p>For more than 30 years, the science has been crystal clear. How dare you continue to look away and come here saying that you’re doing enough, when the politics and solutions needed are still nowhere in sight.</p><p>You say you hear us and that you understand the urgency. But no matter how sad and angry I am, I do not want to believe that. Because if you really understood the situation and still kept on failing to act, then you would be evil. And that I refuse to believe.</p><p>The popular idea of cutting our emissions in half in 10 years only gives us a 50% chance of staying below 1.5 degrees [Celsius], and the risk of setting off irreversible chain reactions beyond human control.</p><p>Fifty percent may be acceptable to you. But those numbers do not include tipping points, most feedback loops, additional warming hidden by toxic air pollution or the aspects of equity and climate justice. They also rely on my generation sucking hundreds of billions of tons of your CO2 out of the air with technologies that barely exist.</p><p>So a 50% risk is simply not acceptable to us – we who have to live with the consequences.</p><p>To have a 67% chance of staying below a 1.5 degrees global temperature rise – the best odds given by the [Intergovernmental Panel on Climate Change] – the world had 420 gigatons of CO2 left to emit back on Jan. 1st, 2018. Today that figure is already down to less than 350 gigatons.</p><p>How dare you pretend that this can be solved with just ‘business as usual’ and some technical solutions? With today’s emissions levels, that remaining CO2 budget will be entirely gone within less than 8 1/2 years.</p><p>There will not be any solutions or plans presented in line with these figures here today, because these numbers are too uncomfortable. And you are still not mature enough to tell it like it is.</p><p>You are failing us. But the young people are starting to understand your betrayal. The eyes of all future generations are upon you. And if you choose to fail us, I say: <strong>We will never forgive you</strong>.</p><p>We will not let you get away with this. Right here, right now is where we draw the line. The world is waking up. And change is coming, whether you like it or not.</p><p>Thank you.”</p><p>~ <strong>Greta Thunberg</strong>, at the Climate Action Summit at <strong>United Nations</strong> headquarters in New York. She sailed to New York City for the event from Sweden on a <strong>zero-emissions sailboat</strong>.</p><p>My intent in publishing this is to only share what Greta Thunberg has said. Nothing more. I couldn’t possibly add anything more to what she has said, even if I tried. But I do believe it’s urgent that all of us know what Climate Change is, and act on that information fast.</p><p><strong>Really fast.</strong></p><p>Note: <em>The cover photo is by </em><a href="https://unsplash.com/photos/4ilIvlK3L14"><em>Markus Spiske</em></a><em> on Unsplash!</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4da99b284af2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bash: Automating Comments Submission for a Static Site]]></title>
            <link>https://medium.com/@raravi/bash-automating-comments-submission-for-a-static-site-3bd60ac6e9c3?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/3bd60ac6e9c3</guid>
            <category><![CDATA[bash]]></category>
            <category><![CDATA[static-site]]></category>
            <category><![CDATA[shell]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Mon, 23 Sep 2019 19:45:55 GMT</pubDate>
            <atom:updated>2019-09-23T19:45:55.228Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*BY3Evxeh4RGe0xYEWvkcfA.png" /><figcaption>Photo by <a href="https://unsplash.com/@franckinjapan">Franck V.</a> on <a href="https://unsplash.com/s/photos/automation">Unsplash</a>.</figcaption></figure><p>A <strong>Static Site</strong> is awesome for bloggers. Easy to create (content), easy to maintain (website). And it allows you to tinker with your website design with just a bit of HTML/CSS know-how. The only issue with <strong>Static Sites</strong> is how to manage the comments section, as a bunch of static pages cannot handle form submission on their own.</p><p>But fear not, a bit of server-side scripting can solve it for you. The comments can be stored as individual files on the server, as I’ve mentioned in a <a href="https://www.amithraravi.com/articles/tech/adding-comments-to-a-static-site/">previous post</a>. After this, all I had to do was download the files on to my local machine and process them. In the beginning, I used to do it every week or so as the volume of comments was quite low. However, in the last six months, I’ve found that the increasing high influx of comments requires a daily check. Or, I will miss the genuine comments in the barrage of spam that hits my website every day.</p><h3>As It Is (or The Current System)</h3><p>I finally found the time to automate comments submission on my <a href="https://www.amithraravi.com/">site</a>. It’s been on my TODO list for so long that getting it done filled me with relief.</p><p>Let me give you a brief description of the setup I have so that you can better understand the automation performed.</p><ol><li>A PHP script on my server picks up the comments received through form submission on my website.</li><li>The script processes the comment and saves it as a <a href="https://yaml.org/">YAML</a> file.</li><li>I log-in periodically and download all the comments to my local machine.</li><li>I check the downloaded comments and delete the spam ones. This remains to be a manual step.</li><li>For each valid comment, I will check the post it belongs to and add it to that particular post.</li><li>Build my website with the new comments.</li><li>Deploy the new build to the web server.</li></ol><p>Out of these steps, Step 4 is a manual one for me. As a result, I have 2 scripts:</p><ol><li><strong>Download comments</strong>: A script to download comments and delete them from the server.</li><li><strong>Process Valid comments</strong>: A script to move each valid script to its post folder, build the website with new comments and deploy it to the web server.</li></ol><p>Even if you are eliminating spam at the web server side (using Google Captcha or something similar), there will be spam leftover for a human to moderate. I would suggest not to eliminate the manual check from your moderation process. <strong>An attacker can design a handcrafted piece of code in a comment to wreak havoc on your web server</strong>. If you’re feeling brave, you can go ahead and write a single script ignoring the manual verification.</p><h3>As It Should Be (or The Automated System)</h3><p>I thought of BASH scripting to automate this process, as I usually have my MacBook Air with me wherever I go. I’m sure I will be using it for many more years to come!</p><h4>Download Comments</h4><p>To download comments, I used <a href="https://linux.die.net/man/1/rsync">rsync</a> Linux command. If the rsync is successful, I delete the downloaded comments from the server. Here is a sample script.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3db345007b7f9c8e8db8c579b80ebe14/href">https://medium.com/media/3db345007b7f9c8e8db8c579b80ebe14/href</a></iframe><p>This part declares the variables to be used.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9e498bfabf0cd1dba19076aa63ddeedd/href">https://medium.com/media/9e498bfabf0cd1dba19076aa63ddeedd/href</a></iframe><p>Execute the rsync command to download the comment YML files.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8310a3c4826e64f0395eaf6b6d9e61ba/href">https://medium.com/media/8310a3c4826e64f0395eaf6b6d9e61ba/href</a></iframe><p>The above part will delete comment files from the server if the rsynccommand is successful.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1a6da05bd86e97c3d8137e6f790a0fc6/href">https://medium.com/media/1a6da05bd86e97c3d8137e6f790a0fc6/href</a></iframe><p>The else part above will usually be run if there are no new comments. I say ‘usually’ because the else part is hit for any other errors as well. So it is better to keep logs of this part!</p><p>Once I run this script, I check all the comments downloaded onto my local machine and delete the spam. Now the remaining comments are ready to be processed by the next script.</p><h4>Process Valid Comments</h4><p>I will go through the script part by part, as before.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9092c2b62a028da03fb1708c4db3de71/href">https://medium.com/media/9092c2b62a028da03fb1708c4db3de71/href</a></iframe><p>The variables are declared here.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3da31b4bd977fa9e23fc665c866d9d39/href">https://medium.com/media/3da31b4bd977fa9e23fc665c866d9d39/href</a></iframe><p>The for loop will process each comment file.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/614d0a5a07e9d05be99f29058966cf8f/href">https://medium.com/media/614d0a5a07e9d05be99f29058966cf8f/href</a></iframe><p>If no files found, exit the loop. Else, move on.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f638e6d64d453a9a924adbdbfccacaa/href">https://medium.com/media/1f638e6d64d453a9a924adbdbfccacaa/href</a></iframe><p>The above part is specific to my code. I check if the comment file has a line starting with slug: . If it does, then it’s a valid comment. Else, move on to the next comment.</p><p>You can do processing specific to your comments in the above part!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5d4ddd48a9e01925f85dae9a10f49964/href">https://medium.com/media/5d4ddd48a9e01925f85dae9a10f49964/href</a></iframe><p>I check for SLUG, if it exists then I move the comment to its post folder. If the post folder doesn’t exist, then I create the post folder and then move the comment.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b2a133f263fec1e2a78decaf2bb90598/href">https://medium.com/media/b2a133f263fec1e2a78decaf2bb90598/href</a></iframe><p>This part gives information about the files that were processed (or not) by the script.</p><h3>BASH Scripting</h3><p>BASH may feel a bit weird to look at, and I agree the syntax is quite unintuitive. But you will get used to it after a while. After you build a small script like this, you will understand how shells work and model your script based on it.</p><p>There’s a caveat to using BASH (or any shell) scripting. Any shell can elevate to root privileges without you, the developer, intending it. And one of the easiest ways to do that is not <a href="https://www.tldp.org/LDP/abs/html/quotingvar.html">quoting your variables</a>. Have a look at the <a href="https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells">stack overflow thread</a>, it’s worth the read.</p><p>I would suggest to run the BASH scripts from your terminal and never from outside your local machine. And this ties in with the manual verification step I’d talked about earlier. If the comment is not checked for spam, a carefully constructed piece of code can use your BASH script to attack your system!!</p><p>Use BASH responsibly, know the risks. It is quite powerful when used the right way.</p><p>I hope this post gave you enough information to automate your site! And Happy <strong>BASH</strong>ing :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3bd60ac6e9c3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CircleCI: A Simple CI/CD Pipeline for Your Static Site]]></title>
            <link>https://medium.com/swlh/circleci-a-simple-ci-cd-pipeline-for-your-static-site-2355874ae6a2?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/2355874ae6a2</guid>
            <category><![CDATA[blog]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[continuous-deployment]]></category>
            <category><![CDATA[circleci]]></category>
            <category><![CDATA[continuous-delivery]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Fri, 20 Sep 2019 00:45:24 GMT</pubDate>
            <atom:updated>2019-09-20T13:32:15.329Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*v71mFkE9ZZw8hgYCOfafGw.png" /></figure><p>For people who want to send their thoughts out into the world, a blog is the perfect medium of delivery. Although the maintenance of a blog feels easy in the beginning, as the content grows with time it becomes difficult to manage the process manually. When the blog hits critical mass, it becomes important to look at automating the maintenance process.</p><p>This is where <strong>CI/CD</strong> tools come in. These tools will automate the testing and deployment stages in a fast and efficient manner.</p><p>Before we get into the nitty-gritty details, let me give you my use-case. My blog is a static site built using Jekyll. After adding content for over a year, the blog has grown large enough that changing one thing may break something else. For testing my builds, below are the high-level steps I wanted automated.</p><ul><li>On every commit to the master branch, take the code hosted on <a href="https://github.com/raravi/amithraravi2.com">my GitHub repository</a> (repo in short).</li><li>Run sanity checks to see there are no breaking changes.</li><li>Deploy to my web server — hosted on a Linux hosted server.</li></ul><p>The repetitive nature of this task made me realize that my blog had grown to a point where using a CI/CD pipeline started to make sense.</p><h3>What is CI/CD?</h3><p><a href="https://en.wikipedia.org/wiki/Continuous_integration">Continuous Integration</a> and <a href="https://en.wikipedia.org/wiki/Continuous_delivery">Continuous Delivery</a> and/or <a href="https://en.wikipedia.org/wiki/Continuous_deployment">Continuous Deployment</a> is the practice of continuously merging all the developers’ code into a single codebase; for automated building, testing, and quicker delivery/deployment. In simple language, the code written by everyone in the team resides in a single place and is always delivery-ready, by running self-testing automated builds on each code check-in.</p><p>The CI/CD process places great importance on releasing software frequently. This will, in turn, lead to faster updates for the product, and a better experience for the user. Here is a <a href="https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment">good CI/CD explainer</a> from Atlassian.</p><p><strong>Continuous Delivery</strong> ensures that the latest code is ready for deployment, by incorporating all the changes successfully up to the present time (e.g., Minor/Major Version releases).</p><p>If <strong>Continuous Deployment</strong> is part of the CI/CD pipeline, then the code is deployed automatically in short cycles (e.g., nightlies).</p><h3>CI/CD for individuals/blog-owners</h3><p>I agree that the complete set of advantages offered by a dedicated CI/CD pipeline is a bit of overkill for us mere mortals. But then, all of us deserve a bit more of automation in our lives, don’t we?! With this spirit, I came up with the 3 steps that I would like to automate :)</p><p>A bit of googling (is this still a thing?!) revealed that a CI/CD pipeline using containers is the fastest way to automate the above requirement. Out of the various options available (the popular ones being <a href="https://jenkins.io/">Jenkins</a>, <a href="https://travis-ci.org/">Travis CI</a>, <a href="https://www.circleci.com/%E2%80%8E">CircleCI</a>, <a href="https://buddy.works/">Buddy</a>, etc..), I zeroed in on <strong>CircleCI</strong>. <strong>CircleCI</strong> is currently offering free accounts for GitHub repo owners, as are a few others listed above.</p><h3>Enter CircleCI</h3><p>Using the <strong>CircleCI</strong> platform, my requirement given above can be automated as follows:</p><ul><li>Create a separate job in the <strong>CircleCI</strong> pipeline to accomplish the step.</li><li>Chain the 3 jobs into a workflow so that there is a logical flow. Say Job 1-&gt; Job 2 -&gt; Job 3. You may also specify the dependency between steps in the workflow, something like Job 2 needs to wait for successful completion of Job 1. Or, that Job 3 will wait for Job 1 and Job 2 to complete.</li><li>Specify the trigger condition for your workflow.</li></ul><h4>A simple CircleCI Job</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6000702e927f00fa3d47336bd3b01641/href">https://medium.com/media/6000702e927f00fa3d47336bd3b01641/href</a></iframe><p>The above <strong>CircleCI</strong> configuration (saved in a CircleCI config.yml file) lists a job called “build” which has 3 steps:</p><ul><li>It spins up a docker image for node.js platform. Think of this step as bringing up the node.js environment for program execution.</li><li>Checks out code — from a GitHub repository that you’ve connected previously.</li><li>Runs echo command inside the docker image.</li></ul><p>A <a href="https://en.wikipedia.org/wiki/Docker_(software)">Docker</a> image is a container that gives the required functionality/environment for running your code. For your project, the container will provide an easy way to install dependencies and run your code in an isolated environment. A container is not fully featured like a VM, but faster to bring up and run code. So it works great for testing individual code components!</p><h4>A more complete example</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5ab50725eeddd0d17023736684d53766/href">https://medium.com/media/5ab50725eeddd0d17023736684d53766/href</a></iframe><p>Now that you have seen jobs in action, it’s time to understand the next level: workflows. A workflow allows you to define the logical sequence of the individual jobs, complete with dependencies between each. In the above example, the build and test jobs run in parallel and once both of them complete successfully, the deploy job is run.</p><h3>Use CircleCI to push changes to your blog</h3><p>If your website code resides on GitHub, you can connect it to CircleCI and start watching your GitHub repo for commits.</p><p>The only thing required is to add the below file to your repo.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b5143a60814d1ed8dd796a6b6eb77100/href">https://medium.com/media/b5143a60814d1ed8dd796a6b6eb77100/href</a></iframe><p>The config.yml file contains the configuration required by CircleCI for the jobs/workflows to be run! And you can keep the config.yml as part of your build. Pretty nifty, right?!</p><p>Next up, is to build your website inside the docker image. My website is built on Jekyll in a Ruby environment. So, I will launch a ruby docker image and build my website in it.</p><p>The build job is given below</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/725ffae4dc4522fac1041fa4eab253d5/href">https://medium.com/media/725ffae4dc4522fac1041fa4eab253d5/href</a></iframe><p>The next step is to run a sanity check on the website, to check if it’s running fine. HTMLProofer checks to see if your rendered website works as intended, and that’s what I use. After this, we will save the website (in the _sitefolder) to be used for deploying in the next job.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50c056e2b2c65599834aabd02a278ffb/href">https://medium.com/media/50c056e2b2c65599834aabd02a278ffb/href</a></iframe><p>The deploy job will first get the data saved from the previous job. Then, it uses the <a href="https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories-on-a-vps">rsync</a> Linux command to sync the _site folder contents to the web server.</p><p>rsync command does the following:</p><ul><li>delete flag: delete the contents in the Destination folder that doesn’t match the contents of Source folder (_site)</li><li>exclude flag: excludes the file/folder on the Destination side from deletion.</li><li>The file/folders to be copied, or only copied if they’ve been modified in any way. And only the modified part is copied, not the entire file!</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/500103a25724a825bca2e2252075b000/href">https://medium.com/media/500103a25724a825bca2e2252075b000/href</a></iframe><p>Well, that’s it! Now, make some changes and commit them to your GitHub repo. And watch the <strong>CircleCI</strong> workflow take over. It took me just a day (and a bit of night :) ) to automate this. Who knows, you may do it in a shorter time.</p><p>Even though I have used <strong>CircleCI</strong> here, you can use any other <strong>CI/CD </strong>solution that is out there. It will follow a similar approach to what is described here. Go ahead and dabble a bit!</p><p>Note: <em>The cover photo is by </em><a href="https://unsplash.com/@jjying"><em>JJ Ying</em></a><em> on </em><a href="https://unsplash.com/"><em>Unsplash</em></a><em>!</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2355874ae6a2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/circleci-a-simple-ci-cd-pipeline-for-your-static-site-2355874ae6a2">CircleCI: A Simple CI/CD Pipeline for Your Static Site</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[JavaScript Event Loop: The Concept]]></title>
            <link>https://medium.com/@raravi/javascript-event-loop-the-concept-c27da0567d53?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/c27da0567d53</guid>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[promises]]></category>
            <category><![CDATA[run-to-completion]]></category>
            <category><![CDATA[event-loop]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Wed, 18 Sep 2019 23:07:54 GMT</pubDate>
            <atom:updated>2019-09-18T23:07:54.332Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*3z-QcoI5A2kyyVYodHa51A.png" /></figure><h4>In order to work with JavaScript (in other words, designing any website; and more recently, the server-side node.js platform) it is necessary to understand how the <strong>Event loop</strong> works.</h4><h3>Event Loop</h3><p>The <strong>Event Loop</strong>, as its name suggests, is a loop which processes events one after the other. It usually takes on the form:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c6b2888fb8a3413eb316cc6cda94402/href">https://medium.com/media/6c6b2888fb8a3413eb316cc6cda94402/href</a></iframe><p>The loop will handle every event as it comes in, in a FIFO (First In First Out) approach. When an event is triggered, it will be added to the <strong>Event loop </strong>queue as a message to be processed and has to wait its turn. Once the event moves to the front of the queue, the JavaScript engine will execute the event. Once an event starts getting processed, it cannot be preempted by another event before it completes. This feature is called <strong>Run-To-Completion</strong> and is quite useful for programmers to understand the nature of JavaScript processing. No new events can kick-off during this period, i.e., Javascript is <strong><em>deterministic</em></strong>.</p><p>When I say kick-off, I mean a new event can’t start processing. But nothing stops a new event from getting on to the queue. After all, a queue is meant for one thing: waiting!</p><p>The queue mentioned above is called the <strong>Message queue</strong>, and each event triggered will create a new message and add it to the queue for processing. The main function of the Event loop is to process the messages (and the corresponding event) in the order they were added to the queue.</p><p>Say, you are calling 2 events one after the other, and the 2nd event needs data that needs to be modified/generated by the first event. As a Web Developer, you expect the 2 events to be processed one after the other. Well then, you’re safe working with JavaScript! Because JavaScript has single-threaded processing built into it. This is referred to as the “Concurrency Model” of the JavaScript engine.</p><h4>Example</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/639736f2ebd168eeea60974c25591a35/href">https://medium.com/media/639736f2ebd168eeea60974c25591a35/href</a></iframe><p>The above code will print [1, 2]. Because the function inside setTimeout()is only executed once the current event queue is empty i.e., after the last console.log() line is executed.</p><p>Note: Check this <a href="http://latentflip.com/loupe/">nifty tool</a> created by Philip Roberts to better visualise how the Event Loop works! Rerun the sample code and just look at what happens. It makes it so easy to understand how exactly JavaScript handles events.</p><h3>Concurrency</h3><p>The Concurrency Model has an interesting side-effect: Since the events are processed in order, the callback functions will never be called before the calling function finishes executing!</p><p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises">Promises</a> are made possible due to this aspect of the JavaScript language. And they’ve made our life simpler, wouldn’t you say?!</p><p>Javascript is single-threaded and non-blocking! Feels like a contradiction, but it isn’t. Let me explain.</p><p>Since events are processed in the same order they’re added to the <strong>Message queue</strong>, you would expect <strong>IO</strong> operations to block further processing till they finish. But it ain’t so. :) Any <strong>IO</strong> operation is performed by firing events to relevant Web APIs, with callback functions attached to these events. The callback functions enable Javascript to perform IO operations in a non-blocking manner.</p><p>Even though JavaScript is a single-threaded, blocking, synchronous language, the environment in which JavaScript is executed allows asynchronous function calls to be performed. By running IO operations through such APIs, JavaScript can handle multiple things without blocking the main thread.</p><h4>Example</h4><p>Here is a sample code for a Submit button used for comment submission. The submit function uses an AJAX call to send the comment to the server, with callback functions for success/error (done/fail) handling.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b335de27dd9cbad0a58a99060c2fc61/href">https://medium.com/media/5b335de27dd9cbad0a58a99060c2fc61/href</a></iframe><p>The comment submission is sent, and the last console.log() is executed without any delay. Whenever the request call returns, it will execute the console.log within!</p><p>This illustrates the non-blocking nature of JavaScript. If the user interacts with the website during the submit call, the website is able to react to the user. The Mozilla docs even go on to say that JavaScript is “<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop#Run-to-completion">Never blocking</a>”.</p><h3>ES6 Promises</h3><p>The only exception to the Message queue concept, is how (or rather when) the Promises are resolved. You would expect a Promise which resolves to be added to the end of the queue for processing. But a Promise is designed to wait the least time possible before execution!</p><p>How would you ensure that a Promise will be executed soon without compromising the <strong>Run-To-Completion</strong> feature? By adding it to the beginning of the queue! So that it gets executed as soon as the current function completes. This will guarantee that an asynchronous call will not have to wait too long after it returns to begin execution.</p><p>I hope this article has shed some light on the Event Loop of the JavaScript language and given you better understanding of the Concurrency Model.</p><p>If you want to understand the Event Loop in depth, there are several resources already available. The ones I found useful are given below:</p><ul><li><a href="https://flaviocopes.com/javascript-event-loop/">The JavaScript Event Loop</a></li><li><a href="https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4">JavaScript Event Loop Explained — Frontend Weekly — Medium</a></li></ul><p>Note: <em>The cover photo is by </em><a href="https://unsplash.com/@pankajpatel"><em>Pankaj Patel</em></a><em> on Unsplash!</em></p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/tech/javascript-event-loop-the-concept/"><em>www.amithraravi.com</em></a><em> on 19 September, 2019.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c27da0567d53" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to make Isotope work in a Gatsby site]]></title>
            <link>https://medium.com/@raravi/how-to-make-isotope-work-in-a-gatsby-site-bc63f4c0b22f?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc63f4c0b22f</guid>
            <category><![CDATA[ui]]></category>
            <category><![CDATA[gatsbyjs]]></category>
            <category><![CDATA[web-design]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Wed, 23 Jan 2019 10:36:00 GMT</pubDate>
            <atom:updated>2019-01-23T18:06:05.692Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*Gn5cgShmCY8PSjxYuOwDeg.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/dzCBKa8rIAM?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Dmitri Popov</a> on <a href="https://unsplash.com/search/photos/grid?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h4>Isotope.js implementation for grid filtering on a Gatsby generated React.js site.</h4><p>In my quest to learn <a href="https://www.gatsbyjs.org/">Gatsby.js</a> and the underlying <a href="https://reactjs.org/">React.js</a> library, I was porting my existing site into a Gatsby site. I had finished the basics and was turning towards the more complex parts of my site.</p><p>This is when I hit the wall, figuratively speaking. <a href="https://isotope.metafizzy.co/">Isotope.js</a> is an external javascript resource that I have used to <a href="https://www.amithraravi.com/articles/">animate the filtering of articles grid on my static site</a>, and connect it to the component using <a href="https://jquery.com/">jQuery</a>. Gatsby being React based, I had to write a component which would take care of rendering as well as the callbacks required to sort/filter using Isotope. This is how I got it to work.</p><h3>Initial Setup</h3><p>Before we delve into the solution, it’s better to understand the React basics that go into making it work.</p><ul><li>A <a href="https://reactjs.org/docs/handling-events.html">React component defined as an ES6 class</a> usually implements event handler as a method of that class. This method has to be ‘bind’ed in the constructor for ‘this’ to work.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3441e03c09df61396e1bf4a4316a6d01/href">https://medium.com/media/3441e03c09df61396e1bf4a4316a6d01/href</a></iframe><ul><li>Toggle the status of the buttons using the state of the component. The function this.setState() is used for this purpose.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dd4c2d74d9d8e12fff791609b17a8e59/href">https://medium.com/media/dd4c2d74d9d8e12fff791609b17a8e59/href</a></iframe><ul><li>Style can be <a href="https://www.gatsbyjs.org/tutorial/part-two/#-build-a-new-page-using-css-modules">imported from CSS/SCSS</a> files into the React component and used as shown below:</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/935cde65a7f5a37843638920ed993965/href">https://medium.com/media/935cde65a7f5a37843638920ed993965/href</a></iframe><p>Say we have 2 groups of items — <strong>Tech</strong> and <strong>Personal</strong> — which would mean we should have three filter states — <strong>All</strong>, <strong>Tech</strong> and <strong>Personal</strong> respectively. Hence, a React component which will have 3 buttons, each having a callback that sets the state of those buttons, can be written as:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/740921435e2ff46cbd762bbdd61846b1/href">https://medium.com/media/740921435e2ff46cbd762bbdd61846b1/href</a></iframe><p>The <strong>GridFilter</strong> component renders a group of 3 buttons. Each button has a callback function for handling the click event. The callback functions are binded in the constructor (without which the call this.handleClick is not possible). The state variable is used to toggle the status of the buttons upon callback.</p><p>The 3 buttons as well as the &lt;div&gt; element containing them have classes - isChecked, filtersButton and filtersButtonGroup respectively. These are used to design the look of the buttons.</p><blockquote><em>What happens when you click a button?</em></blockquote><blockquote><em>Does the button change its look?</em></blockquote><blockquote><em>How does the user know the state of each button?</em></blockquote><p>At a bare minimum, the <strong>button that is clicked should look different compared to the other buttons in the grouping</strong> (this is kind of self explanatory).</p><p>Note that the state variable has 3 variables in it. These store the status of the 3 buttons - All, Tech and Personal. Right now, only the status will get toggled on clicking the buttons. But they are supposed to do something more i.e., filter the posts in the grid and animate the action. This is where Isotope comes in.</p><h3>Install/Setup Isotope.js</h3><p>First, install isotope using npm (or bower).</p><pre>npm install --save isotope-layout</pre><p>Then import it into your <strong>GridFilter</strong> component.</p><pre>import Isotope from &quot;isotope-layout/js/isotope&quot;;</pre><p>If you have a pure HTML page containing a grid with the following hierarchy…</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8bf7f6c64b89147d637f8ccc8bdc0639/href">https://medium.com/media/8bf7f6c64b89147d637f8ccc8bdc0639/href</a></iframe><p>In order to use Isotope on such a grid, initialize Isotope using the class names grid and grid-items.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/08806e7ae8b1153d790a420f3ea4f0c8/href">https://medium.com/media/08806e7ae8b1153d790a420f3ea4f0c8/href</a></iframe><p>For filtering, you would call the arrange() method on the Isotope variable.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ce4ac97614234abf49ac0afa5453c20/href">https://medium.com/media/2ce4ac97614234abf49ac0afa5453c20/href</a></iframe><p>Pretty simple, right? How do we go about doing the same in our React component defined above?</p><h3>Integrating Isotope into React</h3><p>The changes to the React component are done in the 3 handleClick functions. See below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eeda5392540834dd82e5fd5b8a97e3ae/href">https://medium.com/media/eeda5392540834dd82e5fd5b8a97e3ae/href</a></iframe><p>Each of the functions has called the arrange() method to filter the grid items as required. But why is there an initialization done before every call? Ideally, this code should be in the constructor, right?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0617046b101bbce86da01fc2b3986b36/href">https://medium.com/media/0617046b101bbce86da01fc2b3986b36/href</a></iframe><p>Well, I thought so too. And my first implementation had the initialization code in the constructor. But for some reason it didn’t work. I used to get an ‘undefined’ error upon clicking any of the 3 filter buttons. So I moved it into the ComponentDidMount() function thinking it would work from there. But it didn’t either.</p><p>Finally, I came up with the idea of initializing before use in each of the 3 handleClick functions. You can see that the initialising code is called only when the Isotope is undefined, meaning it only runs once.</p><p>Now, you can insert the <strong>GridFilter</strong> React component into any of your pages. All you need to do is supply the class names for your grid and grid-item in the initialization code of the component!</p><p>Ps: If you do get the Isotope initialization to work in the constructor, let me know!</p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/tech/how-to-make-isotope-work-in-a-gatsby-site/"><em>www.amithraravi.com</em></a><em> on January 23, 2019.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc63f4c0b22f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Website Design: Creating the Layout in HTML]]></title>
            <link>https://medium.com/elfsight-blog/website-design-creating-the-layout-in-html-887c6b30cf13?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/887c6b30cf13</guid>
            <category><![CDATA[css]]></category>
            <category><![CDATA[ui-design]]></category>
            <category><![CDATA[grid-layout]]></category>
            <category><![CDATA[html]]></category>
            <category><![CDATA[web-design]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Sat, 29 Dec 2018 10:36:00 GMT</pubDate>
            <atom:updated>2019-04-16T05:33:06.784Z</atom:updated>
            <content:encoded><![CDATA[<h4>You’re done with the <a href="https://www.amithraravi.com/articles/tech/website-design-the-basics/">basic design</a> of your website and now you want to code it in HTML.</h4><p>For this you need to be aware of the different layout options available in HTML/CSS and which of those is the right fit for your website design. Let us go through the options one by one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*WO-qp0_CiTmxoH5JsS-kEQ.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/Ylk5n_nd9dA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Pankaj Patel</a> on <a href="https://unsplash.com/search/photos/website?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>Tables — Do Not Do This!</h3><p>This was used earlier when the web was still in its infancy, and there wasn’t much you could do with a website except display text. The developers had got used to designing websites using &lt;table&gt; element and stuck to it even when new things (CSS, images, animations, small screens) came into the picture.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3220a51385950ec69549147e958330f/href">https://medium.com/media/e3220a51385950ec69549147e958330f/href</a></iframe><p>Note: <em>The above code is from </em><a href="https://marcocrosa.wordpress.com/2013/06/15/a-brief-history-of-html-layouts/"><em>MA.CRO. Mind</em></a><em>.</em></p><p>Websites designed using &lt;table&gt; element are fixed in nature. They can’t be redesigned to handle new changes, everything will have to be rewritten completely. This is because the &lt;table&gt; element is meant to display only tabular data, and nothing more. So do not use it for website layout!</p><p>When we look at the other options available, you will realise why it’s so bad to use the Table-based layout. Especially when you are trying to create responsive websites.</p><p><strong>A bit of history:</strong> When the CSS standard arrived in 1996, it helped alleviate the problems created by table-based layout. The &lt;div&gt; element ruled the layout design for a long time, until the CSS 2.1 standard was finally published in 2011 and float walked in to claim the throne!</p><h3>Float — The Classical Way</h3><p>The CSS Float property is used to float elements in a website. For example, you can float an image next to a body of text. This is &lt;float&gt; in its simplest usage. The same concept can be used to design an entire website.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/76dac4d0e05b45e8942c6be6c6871b4b/href">https://medium.com/media/76dac4d0e05b45e8942c6be6c6871b4b/href</a></iframe><p>For designing an entire website, the basic idea to understand is that the &lt;float&gt; element can be used to design an n-column layout. We can combine this with the &lt;div&gt; element to create a layout as given below.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a2840f012a6a0e50be217ee65c7de98b/href">https://medium.com/media/a2840f012a6a0e50be217ee65c7de98b/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fae675a0e8245e2bdc6c88ac174128b/href">https://medium.com/media/2fae675a0e8245e2bdc6c88ac174128b/href</a></iframe><p>Note: <em>A float column should be cleared, or it will mess up the layout of elements that follow after!</em></p><p>Today, a website can be accessed from so many different devices — mobiles, tablets, laptops, PCs. So, how would you ensure that your website looks good on any device? The answer is <strong>Responsive Web Design</strong>. It has only one guiding principle: <strong><em>A web page should look good on any device!</em></strong></p><p><a href="https://www.w3schools.com/html/html_responsive.asp">w3schools</a> has a rather neat definition: “<em>Responsive Web Design is about using HTML and CSS to automatically resize, hide, shrink, or enlarge, a website, to make it look good on all devices (desktops, tablets, and phones).</em>”</p><p>Now, if you want to make sure that your website is responsive and looks good on all kinds of devices then you can do something like the code below.</p><p>Add the following &lt;meta&gt; element to all your web pages:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/970e5a2615c6c6f848aa044e4e89f1cb/href">https://medium.com/media/970e5a2615c6c6f848aa044e4e89f1cb/href</a></iframe><p>Modify the CSS to add a media query:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7abfc570389927925dccf3872eb7c866/href">https://medium.com/media/7abfc570389927925dccf3872eb7c866/href</a></iframe><p>This basically makes the website display as a single column for devices with resolution smaller than 800px (most tablets and all smartphones). Why do this you ask? Imagine looking at a two-column website on your mobile device and trying to read the content. It’s not appealing, is it?!</p><h3>Flex — The Responsive Way</h3><p>CSS Flexbox makes it quite simple to design flexible responsive layout for websites. It takes the concept behind float and streamlines it for easy adoption. The above code can be rewritten as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b47529364ca2470b32254ad046b9eda6/href">https://medium.com/media/b47529364ca2470b32254ad046b9eda6/href</a></iframe><p>It’s that simple.</p><p>You can imagine your website to be a hierarchy of Flexbox elements, starting with the body element, and diving down into the depths till you reach the individual components on each page. Once you start adding &lt;flex&gt; elements to your website, it will become second nature to think of your layout in terms of &lt;flex&gt; properties. That’s how powerful Flexbox is!</p><p>I won’t add anything more here, because there is a beautiful website which already explains Flexbox and its properties in detail. This <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">CSS Tricks</a> page is my go-to reference for all things <strong>flex</strong>!</p><h3>Grid — The Future</h3><p>By now you should be able to spot the issue with using &lt;flex&gt; to design an entire layout. It is a one-dimensional tool (a row/column layout), and as such has to be adapted to be used for designing a website layout which is two-dimensional. This is why you will end up with a hierarchy of nested Flexbox elements in your layout design.</p><p><strong>Grid</strong> solves this by providing a two-dimensional layout that can be designed as per your requirements. The below code creates a 3-column layout of 8 items.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b3222c881c5b3cf08f5941b28910b768/href">https://medium.com/media/b3222c881c5b3cf08f5941b28910b768/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3d77b7db4d7da869483ab9d9d41b847a/href">https://medium.com/media/3d77b7db4d7da869483ab9d9d41b847a/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/698/0*QriIVOGWeM4ApYXM.png" /></figure><p>Going by the example above, you can design a layout of your website using the CSS Grid as follows.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/427652797beeb827a45b74a11c199009/href">https://medium.com/media/427652797beeb827a45b74a11c199009/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ef2992c031768addcd3f1133b94db233/href">https://medium.com/media/ef2992c031768addcd3f1133b94db233/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/998/0*RBEc4iNzaPGQmy0F.png" /></figure><p>The grid-template-areas is a great way to structure your layout. It’s represented visually in code and is easily understandable. Comparing this with the earlier ways (the rigid structure of the tables, the cumbersome floats and the multi-level hierarchy of the flexbox), we can see how easy the CSS Grid has made designing a layout!</p><p>After going through each of the above, you can see that a pattern has emerged.</p><ul><li>The <strong>CSS Grid</strong> is best suited for designing entire layout of the website.</li><li>The <strong>CSS Flexbox</strong> is optimal for designing individual rows or columns of components.</li><li><strong>Responsive Web Design</strong> should be considered in the beginning stages of website design. You should have a pretty good idea about how your website will look on every kind of device.</li><li>And finally, <strong>DO NOT use Tables</strong> for layout design.</li></ul><p>I hope this post has been easy to understand and has added to your CSS/HTML knowledge. Please don’t hesitate to ask any questions that you may have!</p><p>Until the next bog post..</p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/tech/website-design-creating-the-layout-in-html/"><em>www.amithraravi.com</em></a><em> on December 29, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=887c6b30cf13" width="1" height="1" alt=""><hr><p><a href="https://medium.com/elfsight-blog/website-design-creating-the-layout-in-html-887c6b30cf13">Website Design: Creating the Layout in HTML</a> was originally published in <a href="https://medium.com/elfsight-blog">Elfsight Magazine 🚀</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fake News in India: My Thoughts on the BBC Study]]></title>
            <link>https://medium.com/@raravi/fake-news-in-india-my-thoughts-on-the-bbc-study-4fc04a0d9abc?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/4fc04a0d9abc</guid>
            <category><![CDATA[study]]></category>
            <category><![CDATA[opinion]]></category>
            <category><![CDATA[journalism]]></category>
            <category><![CDATA[india]]></category>
            <category><![CDATA[fake-news]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Tue, 04 Dec 2018 10:36:00 GMT</pubDate>
            <atom:updated>2018-12-06T15:25:31.367Z</atom:updated>
            <content:encoded><![CDATA[<h4>Why do people fall prey to fake news so easily?!</h4><p>The advent of <strong>Fake News</strong> in modern times is seen as a problem primarily to do with advancement in digital technology. Little or no thought is given to why fake news actually exists in today’s fast-moving all-knowing world, or why it spreads so easily. It is critical to think of fake news in these digital times.</p><p>While I have always wondered why so many of my acquaintances on Facebook/Twitter/WhatsApp keep sending information that I’ve found of a dubious nature, I’ve never really found the energy to dig deeper till now. About a week or so ago, I came across this <a href="http://downloads.bbc.co.uk/mediacentre/duty-identity-credibility.pdf">BBC study</a> done on Fake News in various countries, India being one of them. This was of immense interest to me, as I see the significant real-world consequences of fake news in the current political climate.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*NBPwf8AFVK65OjYZ.jpg" /></figure><p>It took me about 3–4 days for me to go through the entire study. The study is quite detailed and employs a qualitative analysis of the representative dataset to try to understand the prevailing situation in India. I urge everyone to go through the study for the sake of understanding why fake news can be so dangerous. If you are still not convinced, please see <a href="https://www.bbc.com/news/world-46146877">this article</a> to get the basics of the study results and find some context for the study was deemed necessary.</p><p>Here is my understanding of the data from the BBC study.</p><h3>The Current Situation</h3><p><strong>Indian media</strong>, especially the vernacular news media, has become sensationalistic and hyperbolic in the way they deliver news daily to its users. People know that most of the coverage is restricted to the news that sells, rather than news that needs to be seen/spread. And this knowledge spurs the growth of alternative news outlets. People are ready to believe what influential individuals in their circles say and broadcast it to all their acquaintances.</p><p>Rather than the authenticity of information, it’s the social influence of the sender that urges the user to forward information deemed to be important for consumption by their peers. And most messages are forwarded without being read, which tells us that people will only give a cursory glance before sending a message on its way to their friends and family. This removes any incentive for producing quality digital content, which can be verified to be true, because it’s so easy to create and share any kind of content.</p><blockquote><em>“What is new though, is that with the definition of news becoming expansive and all-encompassing, we find that anything of importance to the citizen is now considered ‘news’. It then also stands to reason that they are happy receiving information from just about anyone — and not just a handful of news organisations with rigorous journalistic practices, trusted brand images, and legacies of accuracy. Even more importantly for our purposes, we find that people don’t differentiate — or more accurately find it too hard or too resource intensive50 — to differentiate between various sources of news (in the broad sense outlined above). Social media, with its low barriers to entry, provides innumerable sources of information — and the distinctions between them are flattened in the minds of the users.”</em></blockquote><blockquote><em>~ From the study</em></blockquote><h3>The Mindset of the Average Indian User</h3><p>With the Internet being touted to be the greatest thing since the Industrial Revolution, everyone wants to use the Internet and be seen doing it. India arrived quite late to the party, so to speak. And Indians felt left behind. So they lapped up the cheap Internet rates and the equally cheap mobiles which could connect them to the ‘Internet’ being offered due to the entry of <strong>Jio</strong>. Till now, the news was something you could talk face to face in groups. But this push to digital had opened up a new public space. Twitter, WhatsApp, Facebook, and their ilk had opened up a space where people can say and do what they want without being physically there to face the consequences of their actions.</p><p>As such, Indian users embraced these social media spaces as public spaces where they could voice their opinions and engage with like-minded individuals. This meant anyone from any part of India could be in touch with people all over the world. This newfound connectivity excited the Indian user. They were placed in a unique situation of not having experience in handling the informational deluge and yet having the tools to make use of it any way they saw fit.</p><blockquote><em>“WhatsApp groups bring together like-minded people into tight-knit online communities. While this is supposed to be of a positive nature, more often than not this character of WhatsApp is used to mobilise groups to violent action. This is beside the fact that WhatsApp is a platform known for spreading low-quality information of doubtful veracity.”</em></blockquote><blockquote><em>~ From the study</em></blockquote><h3>The Result</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*3M2LDcCy8Ur90ZAY.jpg" /></figure><p>Easy access to the Internet and the resulting information overload has led to:</p><ul><li>Memes — Images with short texts attached to it, are the most shared pieces of ‘information’. Why do people believe memes, when they wouldn’t trust the same information if it was presented on a billboard in their city?!</li><li>The ‘headline’ is the full story. We have developed shorter attention spans to deal with the overabundance of information.</li><li>In-depth information or analysis is often lost to readers. Analyses of the information being presented take valuable time out of the day, this is not acceptable to most users.</li><li>Sharing content is more about ‘feeling’ (socio-political ideology) rather than ‘thinking’ (critical analyses). This point is actually a result of all the above ones. It is easy to express what you feel rather than do a thorough analysis of the information you see.</li></ul><p>So a key feature of online platforms is the sharing of content without active, engaged communication. Share because you feel it is important, not because it really is.</p><blockquote><em>“Most people do not believe they are the ones spreading fake news. For them, the dominant association of fake news is scams and scares, done by nefarious actors for profit making, or at a deeper level fake news is news that is dissonant with their closely held beliefs and self-identity, done by those in a political outgroup. Either way, citizens don’t think they themselves have a role to play in this. This creates a challenge in tackling the spread of fake news: if you don’t believe you have a role to play in the sharing of fake news, then you certainly won’t respond to messages exhorting you to not share fake news.”</em></blockquote><blockquote><em>~ From the study</em></blockquote><h3>The Tools Required to Fight This</h3><p>It’s quite imperative that all of us understand how why widespread the issue of fake news is. The Indian users need to become aware of the way opinion trumps (pun intended) fact in the current political climate. The average Indian user should exercise more caution while browsing information and distributing it to their family and friends. Fake news spreads because people are ready to believe whatever feels right to them — which means they need to mature as responsible users of the Internet age. Also, the society as a whole needs to take cognisance of this issue and work as a community to work on this.</p><p>I will leave you with the following conclusion from the BBC study.</p><blockquote><em>“We have to conclude, though, that checking the flow of fake news, especially in their current predominant form of images and memes is likely to be extremely challenging. We suggest that all actors — platforms, media organisations, government, civil society — come together to tackle the problem, since it is not just a technological problem. But in this, ordinary citizens too, need to take more responsibility about sharing things without verification — and surely, platform-centric solutions to help them can be found without compromising too much on the essential characteristics of the platform. We also recommend that journalists investigate further whether or not there is an organised ecosystem of fake news production and dissemination.”</em></blockquote><blockquote><em>~ From the study</em></blockquote><p>Note: <em>All images used in this post are from </em><a href="https://unsplash.com/"><em>Unsplash</em></a><em>!</em></p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/personal/fake-news-in-india/"><em>www.amithraravi.com</em></a><em> on December 4, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4fc04a0d9abc" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Website Design: The Basics]]></title>
            <link>https://medium.com/@raravi/website-design-the-basics-62831423dc9?source=rss-984ca699f9eb------2</link>
            <guid isPermaLink="false">https://medium.com/p/62831423dc9</guid>
            <category><![CDATA[design]]></category>
            <category><![CDATA[web-design]]></category>
            <category><![CDATA[ui-design]]></category>
            <category><![CDATA[ux-design]]></category>
            <category><![CDATA[wireframe]]></category>
            <dc:creator><![CDATA[Amith Raravi]]></dc:creator>
            <pubDate>Fri, 23 Nov 2018 10:36:00 GMT</pubDate>
            <atom:updated>2019-01-11T08:32:03.231Z</atom:updated>
            <content:encoded><![CDATA[<h4>Once you zero in on the kind of the website you <a href="https://www.amithraravi.com/articles/tech/your-own-website-part-1/">want</a>, the next step obviously is designing it.</h4><p>Figure out the pages you want on your site and what you need each of them to be. Once you have a purpose for each page, you can think of the information to be presented and the kind of layout that goes well with that. In UX design, this process is called <a href="https://theuxreview.co.uk/wireframes-beginners-guide/">wireframing</a>. Wireframing brings out the essentials from the initial concept. It is meant to convert the idea into concrete information, presented visually for easy understanding.</p><p>At its most basic level, wireframing can be just a simple sketch done with pen and paper. For advanced wireframing, you have <a href="https://medium.com/@soulless/the-best-mockup-wireframing-design-tools-apps-for-ui-ux-designers-in-2018-4eb16957e25d">tools available</a>) that help to maintain the same feel across pages and reuse commonly used blocks. Wireframing tools are usually expensive and not really needed for building a personal website. But if you’re looking at a medium sized website for e-commerce purposes then they’re a worthy investment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*mBksMlAyoa-uliKu.jpg" /></figure><p>Okay then, let us deep-dive into the design process and see the steps involved.</p><h3>The Content</h3><p>What is the content that needs to be hosted? A personal blog? A niche market? A portfolio of your work? Each of these is talking to a different audience and the information expected also differs.</p><p>A personal blog is about your one passion turning into much more and hence requires a space to explore it. It will be less formal and more subjective in nature. A marketplace is about selling your goods, which means its all about displaying your product range. A portfolio site is about showcasing your amazing work done through the years (and growing).</p><p>Usually, all of these will require a landing page (SEO talk for your main page), which has the links to all the different sections of your website.</p><ul><li>A blog page listing the posts you have written.</li><li>A products page listing out the products in a grid.</li><li>A portfolio page with all the amazing work you have done.</li></ul><p>Along with these, you will also need a couple of common-purpose pages:</p><ul><li>‘About’ page: It has information on the ‘core functionality’ of the website and the people behind it.</li><li>‘Terms &amp; Conditions’ page: This is essential to address user issues like data privacy and advertising policy. Being transparent from the word ‘go’ is very important in the current political climate.</li></ul><p>Just start with a minimal set of pages that you think are necessary, and add more as you need. This will ensure that you add the core functionality first, and follow through with the bells and whistles later.</p><h3>Layout of your website</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*7SlLDVDgCJ1VPtXx.png" /></figure><p>To achieve a consistent look and feel across your website, all the pages need to conform to one design. This is usually achieved through the same header / footer sections and consistent colour and design choices. Choose a background colour / pattern / image that is relevant to your website. This is what we call the basic template of a website.</p><p>Once the layout of the different pages have been decided upon, the next thing you should think of is navigation. The navigation between the different pages should feel seamless to the user. For example, the Header / Footer sections should contain links to the main pages of your website. Along with the navigation section in the Header, page-specific navigation links offer users easier backlinks to come back to the main sections of the website. In each blog post, a link to the same category of posts is relevant and expected. You can also add links to the next/previous posts at the end of the current post being read. This leads to the evolution of a tree structure of your website, which would be something similar to the one below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/556/0*GwUoYc2cnqxWDIgy.png" /></figure><p>I believe, the number one thing to learn for designing websites is layout design. Or at least a basic understanding of the HTML/CSS elements like the Flexbox and Grid. If you don’t know what they are, then now is a good time for a refresher course on these. To play around with the different layouts and make sure they work as expected, its essential to know how to use these elements to fit your requirements.</p><h3>Prototype It!</h3><p>The first build of your website is just that. It has all the content presented as per the intended design and spread across the different pages. This gives you an overview of how the website will look. Once the initial version is coded, the basic design is complete. This will be your prototype!</p><p>A prototype may not have all the functionality working as expected, but it will have the look and feel of the website as designed. This is the main use of a prototype, it gives you a simplified version of your website for adding in functionality as required. It acts a placeholder for the complete functionality to be added later.</p><p>Once you have a working prototype, you have completed the basic part of your website!</p><p>Note: <em>All images used in this post are from </em><a href="https://unsplash.com/"><em>Unsplash</em></a><em>!</em></p><p><em>Originally published at </em><a href="https://www.amithraravi.com/articles/tech/website-design-the-basics/"><em>www.amithraravi.com</em></a><em> on November 23, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=62831423dc9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>