<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Robert McGovern</title>
    <description>The latest articles on DEV Community by Robert McGovern (@tarasis).</description>
    <link>https://dev.to/tarasis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F295355%2Fd79cb44a-358f-438c-a429-0c03db1f4fc5.JPG</url>
      <title>DEV Community: Robert McGovern</title>
      <link>https://dev.to/tarasis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarasis"/>
    <language>en</language>
    <item>
      <title>What happens when I finish a Frontend Mentor Challenge (or how I build and deploy an 11ty site)</title>
      <dc:creator>Robert McGovern</dc:creator>
      <pubDate>Wed, 22 Feb 2023 23:05:30 +0000</pubDate>
      <link>https://dev.to/tarasis/what-happens-when-i-finish-a-frontend-mentor-challenge-or-how-i-build-and-deploy-an-11ty-site-1a5o</link>
      <guid>https://dev.to/tarasis/what-happens-when-i-finish-a-frontend-mentor-challenge-or-how-i-build-and-deploy-an-11ty-site-1a5o</guid>
      <description>&lt;p&gt;I've been doing challenges from &lt;a href="https://frontendmentor.io" rel="noopener noreferrer"&gt;Frontend Mentor&lt;/a&gt; as a means to practice frontend web development. Specifically working with plain HTML, CSS and JavaScript.&lt;/p&gt;

&lt;p&gt;Rather than just take the simple route of a Git repo per challenge, I put them all in a single repo that is pushed to two&lt;sup id="fnref1"&gt;1&lt;/sup&gt; servers (&lt;a href="https://github.com/tarasis/tarasis.github.io" rel="noopener noreferrer"&gt;Github&lt;/a&gt; and a &lt;a href="https://git.tarasis.net/tarasis/tarasis.github.io" rel="noopener noreferrer"&gt;Gitea&lt;/a&gt; instance).&lt;/p&gt;

&lt;p&gt;The repo is actually a website built with &lt;a href="https://www.11ty.dev" rel="noopener noreferrer"&gt;11ty&lt;/a&gt; and &lt;a href="https://mozilla.github.io/nunjucks/" rel="noopener noreferrer"&gt;Nunjucks&lt;/a&gt; for templating. The challenges, and other pages I build are in the &lt;strong&gt;projects&lt;/strong&gt; directory. They are simply copied over to &lt;strong&gt;www&lt;/strong&gt; during the build.&lt;/p&gt;

&lt;p&gt;When I do a &lt;code&gt;git push all&lt;/code&gt;, on my server it runs a &lt;code&gt;post-receive&lt;/code&gt; script that does the 11ty build. (script below) On Github I use a &lt;strong&gt;Github Action&lt;/strong&gt;&lt;sup id="fnref2"&gt;2&lt;/sup&gt; which builds the site and then a separate action that deploys the page. Vercel watches the main branch on Github for updates and does a similar build action and deployment.&lt;/p&gt;

&lt;p&gt;That is then deployed to three different places: &lt;a href="https://tarasis.github.io" rel="noopener noreferrer"&gt;Github Pages&lt;/a&gt;, &lt;a href="https://tarasis.vercel.app" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, and my own site at &lt;a href="https://rmcg.dev" rel="noopener noreferrer"&gt;rmcg.dev&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Digging a little deeper
&lt;/h2&gt;

&lt;p&gt;The front page of the deployed site acts as a gateway to all of the challenges, for instance this is the newbie section for Frontend Mentor challenges:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftarasis.net%2Fassets%2Fimages%2Fportfolio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftarasis.net%2Fassets%2Fimages%2Fportfolio.png" alt="Screenshot of the newbie section of the my portfolio website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each section is generated from a json file I created (&lt;a href="https://github.com/tarasis/tarasis.github.io/blob/main/src/_data/webprojects.json" rel="noopener noreferrer"&gt;src/_data/webprojects.json&lt;/a&gt;), where I have the service name, location of an svg file, alt text for it, the difficulty level, then there is an array of challenges in that difficulty level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Frontend Mentor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svgSource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/svgs/frontendmentor.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"svgAltText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Frontend Mentor Logo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Collection of challenges I completed for Frontend Mentor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cssClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"difficulty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Junior"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"cssClass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"frontEndMentorChallenges"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"challenges"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Advice Generator App"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/FrontendMentor/junior/advice-generator-app/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"techUsed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"html5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"css3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"js"&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"screenshotURL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/FrontendMentor/junior/advice-generator-app/screenshots/mobile.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"screenshotAltText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Advice Generator App"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the 11ty build occurs, it takes two nunjucks snippets then first takes the service section and fills out the details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;{% for service in webprojects.services %}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"projectsDiv {{service.cssClass}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alignedHeader"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"projectsSection__title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{service.name}}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
            {% if service.svgSource%}
                &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{service.svgSource}}"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"{{service.svgAltText}}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            {% endif %}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        {% if service.description%}
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{service.description}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        {% endif %}

        {% for difficultyLevel in service.difficulty %}
            {% if difficultyLevel.challenges | length %}
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{difficultyLevel.cssClass}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    {% if difficultyLevel.title%}
                        &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;{{difficultyLevel.title}} Challenges&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
                    {% endif %}
                    {% if difficultyLevel.description%}
                        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{difficultyLevel.description}}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                    {% endif %}
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"projects-grid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        {% for challenge in difficultyLevel.challenges %}
                            {% set projectContent = challenge %}
                            {% include "components/project.njk" %}
                        {% endfor %}
                    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            {% endif %}
        {% endfor %}
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you note the &lt;code&gt;div&lt;/code&gt; with class &lt;code&gt;projects-grid&lt;/code&gt;, this is where the second nunjucks snippet occurs. It loops through all of the challenges in the json array represented by &lt;code&gt;difficultyLevel.challenges&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Basically I pass in the challenge to the snippet below, and use the contents to fill out the a card with a screenshot of the finished build, a short description, and shields for HTML/CSS and if used JavaScript. When I get to later challenges I'll add in 11ty, Vue or whatever. (I'll probably simplify the code too so it grabs the tech svg based on the name, rather than having if checks ... we'll see.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;{# {% set projectPrefix = project %} #}

{% if projectContent %}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"project-card stacked"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{projectContent.url}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__img"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{projectContent.screenshotURL}}"&lt;/span&gt;
                        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"{{projectContent.screenshotAltText}}"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                {{projectContent.title}}
            &lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
            {% if projectContent.description | length %}
                &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    {{projectContent.description}}
                &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            {% endif %}
            &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__techUsed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                {% for tech in projectContent.techUsed %}
                    {% if tech === "html5" %}
                        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/svgs/html5.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"HTML5"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                    {% endif %}
                    {% if tech === "css3" %}
                        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/svgs/css3.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"CSS3"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                    {% endif %}
                    {% if tech === "js" %}
                        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/svgs/javascript.svg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"JavaScript"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                    {% endif %}
                {% endfor %}
            &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endif %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When my Git server receives a push, a &lt;code&gt;post-receive&lt;/code&gt; hook is called. It checks that the submission is on the &lt;code&gt;main&lt;/code&gt; branch, and if it is then it installs any needed npm packages, runs &lt;code&gt;npm run build&lt;/code&gt; and then rsyncs the files over to the web server. The script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/srv/gitea
&lt;span class="nb"&gt;source&lt;/span&gt; /srv/gitea/.profile

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PATH&lt;/span&gt;

&lt;span class="c"&gt;# add test so that if bundle isn't found end script&lt;/span&gt;

&lt;span class="c"&gt;#export PATH="$HOME/.rvm/bin:$PATH"&lt;/span&gt;
&lt;span class="c"&gt;#eval "$(rbenv init -)"&lt;/span&gt;

&lt;span class="c"&gt;##############################&lt;/span&gt;
&lt;span class="c"&gt;########## Settings ##########&lt;/span&gt;
&lt;span class="c"&gt;##############################&lt;/span&gt;

&lt;span class="c"&gt;# Useful environment variables (gitea):&lt;/span&gt;
&lt;span class="c"&gt;#   GITEA_REPO_NAME         Repository name&lt;/span&gt;
&lt;span class="c"&gt;#   GITEA_REPO_USER_NAME    Repo owner username&lt;/span&gt;
&lt;span class="c"&gt;#   GITEA_PUSHER_NAME       The username that pushed the commits&lt;/span&gt;
&lt;span class="c"&gt;#   GITEA_AUTHOR            Same as above&lt;/span&gt;
&lt;span class="c"&gt;#   GIT_WORKING_TREE        location to checkout the current tree&lt;/span&gt;

&lt;span class="c"&gt;#   GIT_HOST                Domain name the repo is hosted on. Default: git.starbeamrainbowlabs.com&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_HOST&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;GIT_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git.tarasis.net"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# The url of the repository in question. SSH is recommended, as then you can use a deploy key.&lt;/span&gt;
&lt;span class="c"&gt;# SSH:&lt;/span&gt;
&lt;span class="nv"&gt;GIT_REPO_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_HOST&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GITEA_REPO_USER_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GITEA_REPO_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;# HTTPS:&lt;/span&gt;
&lt;span class="c"&gt;# git_repo_url="https://git.starbeamrainbowlabs.com/${GITEA_REPO_USER_NAME}/${GITEA_REPO_NAME}.git";&lt;/span&gt;

&lt;span class="c"&gt;# The user that pushed the commits&lt;/span&gt;
&lt;span class="nv"&gt;GIT_AUTHOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GITEA_PUSHER_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# The working tree folder&lt;/span&gt;
&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/srv/deploy/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GITEA_REPO_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;##############################&lt;/span&gt;

&lt;span class="c"&gt;###### Internal Settings ######&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;oldref newref ref
&lt;span class="k"&gt;do
    if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ .&lt;span class="k"&gt;*&lt;/span&gt;/main&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Main ref received.  Deploying main branch to production..."&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Creating &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; if needed"&lt;/span&gt;
        &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Checking out repo to working tree folder"&lt;/span&gt;
        git &lt;span class="nt"&gt;--work-tree&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--git-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/srv/gitea/data/gitea-repositories/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_AUTHOR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GITEA_REPO_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt; checkout &lt;span class="nt"&gt;-f&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"cd to &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"install npm modules"&lt;/span&gt;
        npm &lt;span class="nb"&gt;install
        echo&lt;/span&gt; &lt;span class="s2"&gt;"clean old build files"&lt;/span&gt;
        &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; www
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"build files"&lt;/span&gt;
        npm run build
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"rsyncing files to webserver"&lt;/span&gt;
        rsync &lt;span class="nt"&gt;-azv&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GIT_WORKING_TREE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/www/ &amp;lt;REMOVED&amp;gt;@ams.tarasis.net:/srv/http/rmcg.dev &lt;span class="nt"&gt;--delete-after&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Ref &lt;/span&gt;&lt;span class="nv"&gt;$ref&lt;/span&gt;&lt;span class="s2"&gt; successfully received.  Doing nothing: only the main branch may be deployed on this server."&lt;/span&gt;
    &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The finished build is then copied and published.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvements ...
&lt;/h2&gt;

&lt;p&gt;&lt;del&gt;There are improvements I will make at some point, specifically adding optimisation of the images I use. There is little point is downloading a 1440x800px image for the challenge preview when only a small portion of it is shown. I am aware that during the build process you can have 11ty generate more web friendly images at differing sizes.&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;I now do this, but haven't pushed it live yet. I'm waiting till I have completed another Junior level project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;First if you want to know more about whats going on, please do ask I'll do my best to answer. Otherwise I've found 11ty incredibly useful for this purpose, and easy to use. So much so that I have also moved my blog from Jekyll to 11ty, including porting the Minimal Mistakes theme.&lt;/p&gt;

&lt;p&gt;Having a static site where I can quickly add a challenge to the front page without having to repeat html myself is just a such a relief. Especially as the file gets longer and longer :) At this point in time I've finished 17 challenges for Frontend Mentor with 75 ish more to go. There's 1 for Dev Challenges, and 5 for FreeCodeCamp.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; ... There are other project directories that aren't listed on the front page. You can see the code in the projects directory on Github / my gitea instance, and live under &lt;a href="https://rmcg.dev/others/" rel="noopener noreferrer"&gt;others&lt;/a&gt;. They are things I've done based of Youtube videos or other videos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Github build action
&lt;/h3&gt;

&lt;p&gt;My Github 11ty build action&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Eleventy&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

        &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;17.x&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js ${{ matrix.node-version }}&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v2&lt;/span&gt;
              &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node-version }}&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies &amp;amp; build&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                  &lt;span class="s"&gt;npm ci&lt;/span&gt;
                  &lt;span class="s"&gt;npm run build&lt;/span&gt;

            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;peaceiris/actions-gh-pages@v3.7.3&lt;/span&gt;
              &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;publish_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./www&lt;/span&gt;
                  &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Because I like redundancy when I can, and I want control of my code. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;The build action I use is just up above, because apparently I can't have anything below footnotes go figure 🤪 ... ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Border Radius on an Outline in CSS</title>
      <dc:creator>Robert McGovern</dc:creator>
      <pubDate>Wed, 22 Feb 2023 01:58:37 +0000</pubDate>
      <link>https://dev.to/tarasis/border-radius-on-an-outline-in-css-5h23</link>
      <guid>https://dev.to/tarasis/border-radius-on-an-outline-in-css-5h23</guid>
      <description>&lt;p&gt;Yesterday I was fiddling with my blog, adding a button to &lt;a href="https://tarasis.net/2023/2/19/copy-code-blocks/" rel="noopener noreferrer"&gt;copy code blocks&lt;/a&gt; to the clipboard. While I was doing that I figured I'd also add a border to both proper code blocks and to inline code blocks. Something to make them stand out a little more.&lt;/p&gt;

&lt;p&gt;Initially I considered using an &lt;code&gt;outline&lt;/code&gt;, rather than &lt;code&gt;border&lt;/code&gt;. So that it didn't take up pixels as the site uses &lt;code&gt;box-sizing: border-box&lt;/code&gt;. However, I discovered that &lt;code&gt;outline&lt;/code&gt; doesn't really allow you to set a radius. There was no &lt;code&gt;outline-radius&lt;/code&gt; like there is &lt;code&gt;border-radius&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After a bit of searching I came across &lt;a href="https://stackoverflow.com/questions/5394116/outline-radius" rel="noopener noreferrer"&gt;this&lt;/a&gt; post, which has some solutions and workarounds. Someone noted that there was a Firefox only option: &lt;code&gt;-moz-outline-radius&lt;/code&gt;. A later &lt;a href="https://stackoverflow.com/a/66661654" rel="noopener noreferrer"&gt;answer&lt;/a&gt; noted that as of April 2021 in Firefox you could use &lt;code&gt;border-radius&lt;/code&gt; but it was the only browser that supported it.&lt;/p&gt;

&lt;p&gt;So I dutifully tried it out, and yes it did work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv2q2pj8rbqwc6790iy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv2q2pj8rbqwc6790iy5.png" alt="Screenshot of an outline around some code, with a border-radius applied" width="124" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But then I noticed that it was also working in Safari Technology Preview Release 163 &amp;amp; Chrome 110! Unfortunately Safari 16.3 (Desktop) doesn't support it.&lt;/p&gt;

&lt;p&gt;One possible bug I noticed while experimenting was that Safari TP would ignore the outline style &lt;code&gt;dashed&lt;/code&gt; if  &lt;code&gt;border-radius&lt;/code&gt; was set. Safari TP would instead make the outline solid.&lt;/p&gt;

&lt;p&gt;Codepen with example:&lt;/p&gt;

&lt;p&gt;
  &lt;span&gt;See the Pen &lt;a href="https://codepen.io/tarasis/pen/bGxpBdz" rel="noopener noreferrer"&gt;
  Untitled&lt;/a&gt; by Robert McGovern (&lt;a href="https://codepen.io/tarasis" rel="noopener noreferrer"&gt;@tarasis&lt;/a&gt;)
  on &lt;a href="https://codepen.io" rel="noopener noreferrer"&gt;CodePen&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;The results, as you can see below, are rather different between Safari TP v163, Chrome 110.0.5481.100, and Firefox Developer Edition 111.0b3 (64-bit)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safari TP v163&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbv590himz29cbdq81x8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbv590himz29cbdq81x8.png" alt="Image of codepen output in Safari. Of note the second line of text is supposed to be Outlined with border radius, however only the top left and bottom right have curves. The line below should be the same but with dashed line around the text, however the line is solid." width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome 110.0.5481&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fum5ir4tz0tbowy8u0c72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fum5ir4tz0tbowy8u0c72.png" alt="Image of codepen output in Chrome. Of note the second line is properly curved. The line below is correctly dashed." width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firefox Developer Edition 111.0b3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5xdfnyfx5nsedu1ni9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5xdfnyfx5nsedu1ni9c.png" alt="Image of codepen output in Firefox. Of note the second line is outlined with the correct border radius at the beginning and end, however the wrapped text onto the second line has a solid border to its left." width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aside, this is my first dev.to post / crosspost with my blog. Be gentle :)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>security</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
