<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>J.Anteckningar</title>
    <subtitle>J.Anteckningar är en blogg om webbutveckling, programmering och skola.</subtitle>
    <link href="https://jensa.dev/feed.xml" rel="self"/>
    <link href="https://jensa.dev/"/>
    
    <updated>Tue, 10 Mar 2026 00:00:00 GMT</updated>
    
    <id>https://jensa.dev</id>
    <author>
        <name>Jens Andreasson</name>
        <email>jensandreasson77@gmail.com</email>
    </author>
    
    
    <entry>
        <title>Kursmaterial</title>
        <link href="https://jensa.dev/sv/posts/kursmaterial/"/>
        <updated>Tue, 10 Mar 2026 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/kursmaterial/</id>
        <content type="html"><![CDATA[<p>2026, det händer väldigt mycket i världen just nu och allt är inte positivt. Den här sidan har blivit lite eftersatt och det är till stor del för att jag jobbat på att samla material för mina kurser på ett ställe. Det stället är inte den här sidan, som iden var en gång i tiden, mest för att jag inte riktigt var nöjd med det.</p>
<p>Jag hade en ursprunglig tanke att gå tillbaka till <a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">Tema, område, del</a> - sidorna, men jag har velat uppdatera de också. Så när kursen webbserver startade i höstas så började jag samla mina lektionsanteckningar och material. Det resulterade i en ny sida <a href="https://kursmaterial.jensa.dev" target="_blank" rel="noopener">Kursmaterial</a>. Sidan är fortfarande under utveckling och jag har faktiskt testat att låsa materialet bakom en kod.</p>
<p>Iden är att samla material för programmering 1 och 2, webbserver och webbutveckling 1 och 2. När jag skriver det så känns iden rätt orimlig då det rör sig om fem kursböcker, men samtidigt är det något jag skapar och gör löpande. I de här kurserna så har jag enbart använt boken <a href="https://www.studentlitteratur.se/kurslitteratur/teknik/programmering/python-fran-borjan-40543-02/" target="_blank" rel="noopener">Python från början</a> av Jan Skansholm. Det fungerar helt ok och det är bra att ha en kursbok, vilket är en av anledningarna till att jag vill “formalisera” mitt material mer.</p>
<p>Materialet är alltså inte öppet för alla och det är för att jag funderat på att publicera det i någon form ett tag, men jag har inte riktigt bestämt mig. Det finns kod osv. på plats för att exportera allt till en ebok, men vi får se.</p>
<p>Om du är nyfiken och intresserad så går det bra att kontakta mig så kan vi lösa något.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Analytics</title>
        <link href="https://jensa.dev/sv/posts/analytics/"/>
        <updated>Wed, 20 Aug 2025 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/analytics/</id>
        <content type="html"><![CDATA[<p>Det här är en ändring från och med idag, jag testar att använda <a href="https://counter.dev" target="_blank" rel="noopener">counter.dev</a> för att samla in lite användardata för den här sidan.</p>
<p>Counter.dev samlar in anonymiserad användardata som jag kan använda för att se antalet besökare bland annat och det är mest för min egen nyfikenhets skull. Förutom det så sparar bara den här sidan ditt valda tema och om du tillåter den att spara temat (det sparas i localstorage).</p>
<p>Tidigare har jag kört Google Analytics, men jag vill ha en lösning som är hostad i Europa.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Analytics</title>
        <link href="https://jensa.dev/en/posts/analytics/"/>
        <updated>Wed, 20 Aug 2025 00:00:00 GMT</updated>
        <id>https://jensa.dev/en/posts/analytics/</id>
        <content type="html"><![CDATA[<p>This is a change starting today; I’m trying out <a href="https://counter.dev" target="_blank" rel="noopener">counter.dev</a> to collect some user data for this site.</p>
<p>Counter.dev collects anonymized user data that I can use to see the number of visitors, among other things, and it’s mostly for my own curiosity. Other than that, this site only saves your chosen theme and whether you allow it to save the theme (it’s stored in localStorage).</p>
<p>Previously, I used Google Analytics, but I want a solution that is hosted in Europe.</p>
<p>This is translated with copilot from the Swedish version of this post.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>The search function is back!</title>
        <link href="https://jensa.dev/en/posts/the-search-function-is-back/"/>
        <updated>Wed, 30 Apr 2025 00:00:00 GMT</updated>
        <id>https://jensa.dev/en/posts/the-search-function-is-back/</id>
        <content type="html"><![CDATA[<p>So when I first created this site I used a search function that I based on an blog post, <a href="https://www.belter.io/eleventy-search/" target="_blank" rel="noopener">eleventy search</a> written by <a href="https://www.belter.io/" target="_blank" rel="noopener">Duncan McDougall</a>, it was a great post and it solved something that I wanted for my site. It was a basic search function and it worked. Essentially it parsed all the pages on the site and created a JSON file with all the content that could be searched using <a href="http://elasticlunr.com/" target="_blank" rel="noopener">elasticlunr</a>.</p>
<h2 id="the-problem" tabindex="-1">The problem</h2>
<p>Fast forward to <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy 3</a> and it no longer worked. It kept spitting errors during the build process. This was due to the process being asynchronous and it didn’t resolve properly.</p>
<p>The error looked like this:</p>
<pre class="language-bash"><code class="language-bash"><span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> Unhandled rejection <span class="token keyword">in</span> promise:
<span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> Unfortunately you’re using code that monkey patched some Eleventy internals and it isn’t async-friendly. Change your code to use the async <span class="token variable"><span class="token variable">`</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token variable">`</span></span> method on the template instead<span class="token operator">!</span>
<span class="token punctuation">[</span>11ty<span class="token punctuation">]</span>
<span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> Original error stack trace: Error: Unfortunately you’re using code that monkey patched some Eleventy internals and it isn’t async-friendly. Change your code to use the async <span class="token variable"><span class="token variable">`</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token variable">`</span></span> method on the template instead<span class="token operator">!</span></code></pre>
<p>So Eleventy suggested a solution, and I didn’t get it to work at the time. But I’ve now revisited the problem and sorted it out. So I thought I would share the solution here, in case someone else has the same problem.</p>
<h2 id="the-solution" tabindex="-1">The solution</h2>
<p>So the solution is indeed to use the async <code>read()</code> method on the template instead of the <code>page.template</code> object to read the content of the page. The <code>page.template</code> object was not async-friendly, and it was causing the error.</p>
<p>This is the updated code that I used to create the search index:</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> elasticlunr <span class="token keyword">from</span> <span class="token string">"elasticlunr"</span>

<span class="token keyword">const</span> <span class="token function-variable function">searchFilter</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">collection</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token comment">// what fields we'd like our index to consist of</span>
    <span class="token keyword">const</span> index <span class="token operator">=</span> <span class="token function">elasticlunr</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addField</span><span class="token punctuation">(</span><span class="token string">"title"</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addField</span><span class="token punctuation">(</span><span class="token string">"summary"</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addField</span><span class="token punctuation">(</span><span class="token string">"tags"</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">addField</span><span class="token punctuation">(</span><span class="token string">"category"</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setRef</span><span class="token punctuation">(</span><span class="token string">"id"</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    <span class="token comment">// loop through each page and add it to the index</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> page <span class="token keyword">of</span> collection<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">const</span> <span class="token punctuation">{</span> data <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">await</span> page<span class="token punctuation">.</span>template<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

        <span class="token comment">// if the page is excluded from collections, skip it</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>eleventyExcludeFromCollections<span class="token punctuation">)</span> <span class="token keyword">continue</span>
        <span class="token comment">// if the page is not a post, skip it</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>page<span class="token punctuation">.</span>url<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"/posts/"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">continue</span>
        <span class="token comment">// if the page is not a markdown file, skip it</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>page<span class="token punctuation">.</span>inputPath<span class="token punctuation">.</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token string">".md"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">continue</span>

        index<span class="token punctuation">.</span><span class="token function">addDoc</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
            <span class="token literal-property property">id</span><span class="token operator">:</span> page<span class="token punctuation">.</span>url<span class="token punctuation">,</span>
            <span class="token literal-property property">title</span><span class="token operator">:</span> data<span class="token punctuation">.</span>title<span class="token punctuation">,</span>
            <span class="token literal-property property">summary</span><span class="token operator">:</span> data<span class="token punctuation">.</span>summary <span class="token operator">||</span> <span class="token string">""</span><span class="token punctuation">,</span>
            <span class="token literal-property property">tags</span><span class="token operator">:</span> data<span class="token punctuation">.</span>tags <span class="token operator">?</span> data<span class="token punctuation">.</span>tags<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span>
            <span class="token literal-property property">category</span><span class="token operator">:</span> data<span class="token punctuation">.</span>category <span class="token operator">||</span> <span class="token string">""</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> index<span class="token punctuation">.</span><span class="token function">toJSON</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> searchFilter <span class="token punctuation">}</span></code></pre>
<p>So the code is mostly the same as before, but now we use <code>await page.template.read()</code> to get the data from the page. This is an async function that returns a promise, and it resolves to the data object that we need.<br>
This means that we can now use the <code>data</code> object to get the properties we need for the search index.</p>
<p>Now it’s just a case of using the <code>searchFilter</code> function to generate the search index and save it to a JSON file. I do this in the same way as in the original post, with a <code>search-index.json.njk</code> file.</p>
<pre class="language-njk"><code class="language-njk"><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span>
<span class="token variable">permalink</span><span class="token punctuation">:</span> <span class="token operator">/</span><span class="token variable">search</span><span class="token operator">-</span><span class="token variable">index</span><span class="token punctuation">.</span><span class="token variable">json</span>
<span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span>

<span class="token punctuation">{</span><span class="token punctuation">{</span> <span class="token variable">collections</span><span class="token punctuation">.</span><span class="token variable">search</span> <span class="token operator">|</span> <span class="token variable">searchFilter</span> <span class="token operator">|</span> <span class="token variable">dump</span> <span class="token operator">|</span> <span class="token variable">safe</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre>
<h2 id="conclusion" tabindex="-1">Conclusion</h2>
<p>So that’s it! I hope this helps someone else who is having the same problem. The search function is now working again, and I’m happy to have it back on my site.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Jul och partikelsnö</title>
        <link href="https://jensa.dev/sv/posts/jul-och-partikelsno/"/>
        <updated>Tue, 17 Dec 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/jul-och-partikelsno/</id>
        <content type="html"><![CDATA[<p>Uppdatering, nytt år, mindre snö. Snön har slutat falla och partiklarna har plockats undan för året. Koden finns fortfarande tillgänglig på <a href="https://github.com/jensadev/wu1-vinter" target="_blank" rel="noopener">Github - wu1-vinter</a>.</p>
<p>I flera år har vi avslutat terminen med att skapa någon form av julkort (eller vinterkort). Korten har kommit i lite olika former men de flesta har inkluderat någon form av partikelsnö. Så även i år och nu har jag använt koden på den här sidan också.</p>
<blockquote>
<p>Nej, se det snöar, nej, se det snöar, det var väl partiklar, hurra!</p>
</blockquote>
<h2 id="hur-funkar-det%3F" tabindex="-1">Hur funkar det?</h2>
<p>För att skapa och rita ut partiklarna använder jag mig av ett canvas-element. Med javascript ritas sedan partiklarna ut på canvasen. Partiklarna rör sig sedan i slumpmässiga riktningar och hastigheter. När en partikel har rört sig tillräckligt långt utanför canvasen så tas den bort och en ny partikel skapas.</p>
<p>Själva uppdateringen och ritandet av partiklarna sker i en loop som körs med <code>requestAnimationFrame</code>.</p>
<h2 id="uppgiften" tabindex="-1">Uppgiften</h2>
<p>Uppgiften jag skapat finns på <a href="https://github.com/jensadev/wu1-vinter" target="_blank" rel="noopener">Github - wu1-vinter</a>, den är gjort för kursen webbutveckling 1. Eftersom det är i webbutveckling 1 så finns inga krav på programmering.</p>
<p>Inlämningen sker i form av en julhälsning med sidan hostad på Github Pages.</p>
<h3 id="variant-f%C3%B6r-webbserver" tabindex="-1">Variant för webbserver</h3>
<p>Vi har även gjort en julkorts-variant för webbserverprogrammering 1, där vi använder query parametrar på en Express-server för att skapa en personlig hälsning. Servern hostar vi på <a href="https://perfect-delirious-mambo.glitch.me/?title=God%20jul&amp;message=med%20webbserver" target="_blank" rel="noopener">Glitch - Vinterkort</a>.</p>
<p>Inlämningen är även här en länk med julhälsning.</p>
<h2 id="s%C3%A4kerhet" tabindex="-1">Säkerhet</h2>
<p>För att ha ett uns säkerhet så ändras värdet på frontend varianten av sidan med element.textContent istället för innerHTML. Detta för att undvika att någon skickar in skadlig kod i query parametrarna.</p>
<p>På backend varianten så används query parametrarna för att skapa hälsningen, men eftersom det går genom nunjucks så säkras innehållet. Vill du testa den osäkra varianten så behöver du använda <code>safe</code> filtret i din nunjucks-template.</p>
<p>En <a href="https://perfect-delirious-mambo.glitch.me/?r=20&amp;g=250&amp;b=190&amp;title=%3Cscript%3Ealert(%22xss%22)%3C/script%3E&amp;message=%3Cscript%3Ealert(%22xss%22)%3C/script%3E" target="_blank" rel="noopener">säker jul</a> till er alla.</p>
<h2 id="sammanfattning" tabindex="-1">Sammanfattning</h2>
<p>Så med det sagt, jag önskar er alla en riktigt god jul och ett gott nytt år!</p>
<p>Letar du koden så finns den på GitHub.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Christmas and Particle Snow</title>
        <link href="https://jensa.dev/en/posts/christmas-and-particle-snow/"/>
        <updated>Tue, 17 Dec 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/en/posts/christmas-and-particle-snow/</id>
        <content type="html"><![CDATA[<p>Update, new year, less snow. The snow has stopped falling, and the particles have been put away for the year. The code is still available on <a href="https://github.com/jensadev/wu1-vinter" target="_blank" rel="noopener">Github - wu1-vinter</a>.</p>
<p>For several years, we have ended the term by creating some form of Christmas card (or winter card). The cards have come in various forms, but most have included some form of particle snow. This year is no different, and now I have used the code on this page as well.</p>
<blockquote>
<p>Look, it’s snowing, look, it’s snowing, it must be particles, hooray!</p>
</blockquote>
<h2 id="how-does-it-work%3F" tabindex="-1">How does it work?</h2>
<p>To create and draw the particles, I use a canvas element. With JavaScript, the particles are then drawn on the canvas. The particles move in random directions and speeds. When a particle has moved far enough outside the canvas, it is removed, and a new particle is created.</p>
<p>The actual updating and drawing of the particles occur in a loop that runs with <code>requestAnimationFrame</code>.</p>
<h2 id="the-task" tabindex="-1">The Task</h2>
<p>The task I created is available on <a href="https://github.com/jensadev/wu1-vinter" target="_blank" rel="noopener">Github - wu1-vinter</a>, and it is made for the Web Development 1 course. Since it is in Web Development 1, there are no programming requirements.</p>
<p>The submission is in the form of a Christmas greeting with the page hosted on GitHub Pages.</p>
<h3 id="variant-for-web-server" tabindex="-1">Variant for Web Server</h3>
<p>We have also made a Christmas card variant for Web Server Programming 1, where we use query parameters on an Express server to create a personal greeting. We host the server on <a href="https://perfect-delirious-mambo.glitch.me/?title=God%20jul&amp;message=med%20webbserver" target="_blank" rel="noopener">Glitch - Vinterkort</a>.</p>
<p>The submission here is also a link with a Christmas greeting.</p>
<h2 id="security" tabindex="-1">Security</h2>
<p>To ensure a bit of security, the value on the frontend version of the page is changed with element.textContent instead of innerHTML. This is to prevent someone from injecting malicious code into the query parameters.</p>
<p>In the backend version, the query parameters are used to create the greeting, but since it goes through Nunjucks, the content is secured. If you want to test the insecure version, you need to use the <code>safe</code> filter in your Nunjucks template.</p>
<p>A <a href="https://perfect-delirious-mambo.glitch.me/?r=20&amp;g=250&amp;b=190&amp;title=%3Cscript%3Ealert(%22xss%22)%3C/script%3E&amp;message=%3Cscript%3Ealert(%22xss%22)%3C/script%3E" target="_blank" rel="noopener">safe christmas</a> to you all.</p>
<h2 id="summary" tabindex="-1">Summary</h2>
<p>So with that said, I wish you all a very Merry Christmas and a Happy New Year!</p>
<p>If you’re looking for the code, it’s available on GitHub.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Textäventyr med javascript, en fortsättning</title>
        <link href="https://jensa.dev/sv/posts/textaventyr-med-javascript-en-fortsattning/"/>
        <updated>Thu, 17 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/textaventyr-med-javascript-en-fortsattning/</id>
        <content type="html"><![CDATA[<p>När jag avslutade den föregående texten om textäventyr med JavaScript hade vi skapat en struktur för äventyret och två funktioner för att presentera det. I den här delen bygger vi vidare på detta.</p>
<h2 id="funktionerna" tabindex="-1">Funktionerna</h2>
<p>För att presentera äventyret så skapade vi en funktion, <code>displayPage</code> som tar en sida som argument och skriver ut sidans beskrivning och val.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">displayPage</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>page<span class="token punctuation">.</span>description<span class="token punctuation">)</span>
  page<span class="token punctuation">.</span>choices<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">choice</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>choice<span class="token punctuation">.</span>description<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>För att kunna använda <code>displayPage</code>  behövde vi hitta rätt sida i äventyret. Detta löste vi med en funktion, findPage, som tar ett id som argument och returnerar rätt sida.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findPage</span><span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> book<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> page<span class="token punctuation">.</span>id <span class="token operator">===</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="presentera-%C3%A4ventyret" tabindex="-1">Presentera äventyret</h2>
<p>Vi använder funktionerna för att hitta en sida och sedan presentera den. I nuläget fungerar detta som en typ av “game-loop”. Spelaren gör val och klickar sig igenom äventyret.</p>
<p>För att utveckla spelet vidare kommer vi senare att introducera element som kan göra spelet och sidorna mer interaktiva. Men först, presentationen.</p>
<h2 id="html" tabindex="-1">HTML</h2>
<p>För att presentera äventyret så skapar vi en grundläggande HTML sida. Vi använder en <code>main</code> tagg för allt innehåll. I main skapar vi sedan varje sida i spelet som en <code>article</code> tagg. I artikeln så skapar vi en <code>p</code> tagg för beskrivningen och en <code>ul</code> tagg för valen. I <code>ul</code> taggen kommer vi att iterera över valen och skapa en <code>li</code> tagg för varje val.</p>
<p>Det här ger oss en semantiskt korrekt struktur för att presentera äventyret.</p>
<pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>page<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>description<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>choices<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>article</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>Jag inkluderar inte några stilar i detta exempel, det finns många sätt att göra det på och du kan hitta hur jag gjort det i tidigare texter.</p>
<h2 id="javascript" tabindex="-1">Javascript</h2>
<p>Med javascript kan vi sedan manipulera HTML strukturen för att presentera äventyret. Först behöver vi hitta elementen i HTML. För det använder vi <code>document.querySelector</code>. Vi hittar elementen för sidan, beskrivningen och valen.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> pageElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#page"</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> descriptionElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#description"</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> choicesElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#choices"</span><span class="token punctuation">)</span></code></pre>
<p>Vi kan sedan använda dessa element för att uppdatera <code>displayPage</code> funktionen. I funktionen använder vi <code>element.textContent</code> för att redigera text. För att skapa nya element använder vi <code>document.createElement</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">displayPage</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  descriptionElement<span class="token punctuation">.</span>textContent <span class="token operator">=</span> page<span class="token punctuation">.</span>description
  choicesElement<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">""</span>
  page<span class="token punctuation">.</span>choices<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">choice</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> li <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"li"</span><span class="token punctuation">)</span>
    <span class="token keyword">const</span> button <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span>
    button<span class="token punctuation">.</span>textContent <span class="token operator">=</span> choice<span class="token punctuation">.</span>description
    button<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"click"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> nextPage <span class="token operator">=</span> <span class="token function">findPage</span><span class="token punctuation">(</span>choice<span class="token punctuation">.</span>target<span class="token punctuation">)</span>
      <span class="token function">displayPage</span><span class="token punctuation">(</span>nextPage<span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    li<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>button<span class="token punctuation">)</span>
    choicesElement<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>li<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p><code>displayPage</code> använder nu <code>descriptionElement</code> och <code>choicesElement</code> för att visa berättelsen och valen. Vi skapar en <code>li</code> tagg för varje val och lägger till en knapp med en eventlyssnare som kallar <code>displayPage</code> med rätt sida när användaren klickar på valet.<br>
För att ersätta nuvarande sida så skriver vi över innehållet i <code>choicesElement</code> med en tom sträng innan vi lägger till nya val.</p>
<h2 id="testa" tabindex="-1">Testa</h2>
<p>Nu kan vi testa vår funktion för att presentera äventyret. Vi skapar en array med sidor och val och anropar <code>displayPage</code> med den första sidan.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> book <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå till dörren"</span><span class="token punctuation">,</span>
        <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå till fönstret"</span><span class="token punctuation">,</span>
        <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">5</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Du står framför dörren. Vad gör du?"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
      <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Öppna dörren"</span><span class="token punctuation">,</span>
      <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">2</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå tillbaka"</span><span class="token punctuation">,</span>
      <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">0</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Dörren öppnar sig och du ser en korridor. Vad gör du?"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
      <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå framåt"</span><span class="token punctuation">,</span>
      <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">3</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå tillbaka"</span><span class="token punctuation">,</span>
      <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">0</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span></code></pre>
<p>Starta äventyret i din kod med:</p>
<pre class="language-js"><code class="language-js"><span class="token function">displayPage</span><span class="token punctuation">(</span>book<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span></code></pre>
<p>Du är fri att strukturera äventyret och dess filer som du vill, men det kan vara en bra idé att separera JavaScript från HTML och CSS. Detta gör det enklare att underhålla och utveckla koden. Jag rekommenderar även att ha äventyret i en separat fil, inte i din JavaScript-fil. Du kan till och med välja att spara det i en JSON-fil eller en databas.</p>
<h2 id="testa-%C3%A4ventyret-p%C3%A5-codepen" tabindex="-1">Testa äventyret på Codepen</h2>
<p>Här är en länk till en Codepen med all kod:</p>
<div class="feature region">
    <p class="codepen" 
      data-height="600"
      data-default-tab="html,result"
      data-slug-hash="abeWxGa" 
      data-user="jensadev"
      style="height: 600px;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 2px solid;
        margin: 1em 0;
        padding: 1em;">
      <span>See the Pen <a href="https://codepen.io/jensadev/pen/abeWxGa">
        Text adventure</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
        on <a href="https://codepen.io">CodePen</a>.</span>
    </p>
    <script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
  </div>
<h2 id="ladda-%C3%A4ventyret-fr%C3%A5n-json" tabindex="-1">Ladda äventyret från JSON</h2>
<p>För att ladda äventyret från en separat fil så kan du använda <code>fetch</code> för att hämta filen och sedan <code>json</code> för att konvertera den till ett javascript objekt.</p>
<pre class="language-js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"adventure.json"</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token operator">=></span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token function">displayPage</span><span class="token punctuation">(</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<p>JSON är väldigt likt den array vi skapade tidigare. Här är ett exempel på hur JSON-filen kan se ut:</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token property">"description"</span><span class="token operator">:</span> <span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">,</span>
    <span class="token property">"choices"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
        <span class="token property">"description"</span><span class="token operator">:</span> <span class="token string">"Gå till dörren"</span><span class="token punctuation">,</span>
        <span class="token property">"target"</span><span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        <span class="token property">"description"</span><span class="token operator">:</span> <span class="token string">"Gå till fönstret"</span><span class="token punctuation">,</span>
        <span class="token property">"target"</span><span class="token operator">:</span> <span class="token number">5</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span></code></pre>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>I den här delen har vi använt den skapade strukturen för att presentera äventyret. Vi har skapat en grundläggande HTML-sida och använt JavaScript för att manipulera sidan. Vi har även tittat på hur du kan ladda äventyret från en fil.</p>
<p>Du har nu en grund att stå på för att bygga vidare på ditt textäventyr. Du kan lägga till fler sidor, fler val och fler funktioner. Du kan även lägga till bilder genom att inkludera värden i äventyrsobjektet och sedan rita ut dem med <code>displayPage</code> funktionen.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>(om)Installera WSL</title>
        <link href="https://jensa.dev/sv/posts/ominstallera-wsl/"/>
        <updated>Mon, 14 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/ominstallera-wsl/</id>
        <content type="html"><![CDATA[<p>Så mitt WSL började bete sig väldigt konstigt häromdagen. Främst så var det filsystemet som knappt reagerade, filer kunde inte skrivas och det var allmänt segt. Det började med uppgraderingen av Eleventy till version 3 och npm som tuggade i evigheter. Vad det berodde på, det är oklart, men jag tog och avinstallerade WSL och installerade om allt från början.</p>
<p>Så här är en minnesanteckning för mig själv, med fantasi kanske det kan även kan kallas en guide.</p>
<h2 id="installera-wsl" tabindex="-1">Installera WSL</h2>
<p>Jag började med att ta bort min tidigare disitrbution, Ubuntu 20.04. Det gjorde jag genom att köra PowerShell som administratör och skriva:</p>
<pre class="language-powershell"><code class="language-powershell">wsl <span class="token operator">--</span>unregister Ubuntu-20<span class="token punctuation">.</span>04</code></pre>
<p>Efter jag gjort det så tog jag bort WSL genom att slå av det i windows-features, jag fick sedan starta om, slå på WSL och starta om igen.</p>
<p>När det var klart så hämtade jag senaste Ubuntu genom Microsoft Store och installerade det (det är fortfarande lite lustigt kan jag tycka). Jag startade upp Ubuntu och skapade en användare och lösenord.</p>
<h2 id="installera-oh-my-zsh" tabindex="-1">Installera Oh my Zsh</h2>
<p>Jag har övergivit bash för Oh my Zsh för länge sedan. Varför har jag nog inget bra svar på annat än att det krävdes för att få vissa teman att fungera.</p>
<p>Vi behöver först installera Zsh, det gör vi genom att köra:</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> <span class="token function">zsh</span></code></pre>
<p>Sedan kan vi följa instruktioner från <a href="https://ohmyz.sh/#install" target="_blank" rel="noopener">Oh my Zsh</a>.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sh</span> <span class="token parameter variable">-c</span> <span class="token string">"<span class="token variable"><span class="token variable">$(</span><span class="token function">curl</span> <span class="token parameter variable">-fsSL</span> https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh<span class="token variable">)</span></span>"</span></code></pre>
<p>Nu kan nästan det roliga börja.</p>
<h3 id="men-f%C3%B6rst-beh%C3%B6ver-vi-fixa-en-font-i-windows" tabindex="-1">Men först behöver vi fixa en font i Windows</h3>
<p>Vi behöver en font som stödjer alla tecken som vi vill använda, alltså programmeringsrelaterade tecken. Jag använder <a href="https://www.nerdfonts.com/font-downloads" target="_blank" rel="noopener">Fira Code</a> från Nerdfonts och har den installerad i Windows.</p>
<p>Jag använder mig av <a href="https://www.microsoft.com/store/productId/9N0DX20HK701?ocid=pdpshare" target="_blank" rel="noopener">Windows terminal</a> och där kan jag ställa in vilken font som ska användas. Så i settings för Ubuntu profilen så ställer jag in Fira Code som font.</p>
<p>Och så behöver terminalen ett tema, <a href="https://windowsterminalthemes.dev/" target="_blank" rel="noopener">Windows Terminal Themes</a>. Jag gillar <a href="https://windowsterminalthemes.dev/?theme=Mirage" target="_blank" rel="noopener">Mirage</a> vilket jag även använder i min <a href="https://marketplace.visualstudio.com/items?itemName=gerane.Theme-Mirage" target="_blank" rel="noopener">VS Code</a>.</p>
<p>När du hämtar ett tema från Windows Terminal Themes så får du ett JSON objekt som du kan importera i Windows Terminal. Öppna settings och ladda json-filen. Leta reda på <code>schemes</code> och klistra sedan in din kopierade json i arrayen. Välj sedan ditt nya tema i profilen för Ubuntu.</p>
<h2 id="konfigurera-oh-my-zsh" tabindex="-1">Konfigurera Oh my Zsh</h2>
<p>Eftersom vi redan har ett tema från windows terminalen så behöver vi inte använda ett tema från Oh my Zsh annat än för att få andra funktioner. Jag använder ett tema som heter <a href="https://github.com/spaceship-prompt/spaceship-prompt" target="_blank" rel="noopener">Spaceship-prompt</a>. Installationsinstruktioner finns på deras GitHub.</p>
<ol>
<li>Kontrollera så att du kör <code>zsh &gt; 5.8.1</code> genom att köra <code>echo $ZSH_VERSION</code>.</li>
<li>Se till att du har en Nerd Font installerad.</li>
<li>Klona repot, <code>git clone https://github.com/spaceship-prompt/spaceship-prompt.git &quot;$ZSH_CUSTOM/themes/spaceship-prompt&quot; --depth=1</code>.</li>
<li>Skapa en symbolisk länk, <code>ln -s &quot;$ZSH_CUSTOM/themes/spaceship-prompt/spaceship.zsh-theme&quot; &quot;$ZSH_CUSTOM/themes/spaceship.zsh-theme&quot;</code>.</li>
<li>Ange temat i din <code>.zshrc</code>-fil, <code>ZSH_THEME=&quot;spaceship&quot;</code>.</li>
</ol>
<p>Genom att köra <code>omz reload</code> så ska du se det nya temat.</p>
<p><picture><source type="image/webp" srcset="/img/Bv9nKZh3T_-300.webp 300w, /img/Bv9nKZh3T_-600.webp 600w, /img/Bv9nKZh3T_-900.webp 900w" sizes="100vw"><img alt="Windows terminal med Zsh och Spaceship-prompt" loading="lazy" decoding="async" src="/img/Bv9nKZh3T_-300.jpeg" width="900" height="622" srcset="/img/Bv9nKZh3T_-300.jpeg 300w, /img/Bv9nKZh3T_-600.jpeg 600w, /img/Bv9nKZh3T_-900.jpeg 900w" sizes="100vw"></picture></p>
<p>För att konfigurera temat så följer vi instruktionerna på <a href="https://spaceship-prompt.sh/config/intro/" target="_blank" rel="noopener">Spaceship config</a>. Det börjar med att skapa en configurationsfil, <code>touch ~/.spaceshiprc.zsh</code> där vi kan konfigurera temat som vi önskar.</p>
<p>Jag har just nu bara ändrat färgerna på git-statusen och lagt till en emoji för att visa vilken branch jag är på.</p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># Do not truncate path in repos</span>
<span class="token assign-left variable">SPACESHIP_DIR_TRUNC_REPO</span><span class="token operator">=</span>false</code></pre>
<h3 id="plugins" tabindex="-1">Plugins</h3>
<p>Det finns ett stort antal plugins, för zsh och Oh my Zsh. Jag använder mig av.</p>
<ul>
<li><a href="https://github.com/zsh-users/zsh-autosuggestions/tree/master" target="_blank" rel="noopener">zsh-autosuggestions</a></li>
<li><a href="https://github.com/supercrabtree/k" target="_blank" rel="noopener">K</a></li>
</ul>
]]></content>
    </entry>
    
    
    <entry>
        <title>Den engelska versionen har landat</title>
        <link href="https://jensa.dev/sv/posts/den-engelska-versionen-har-landat/"/>
        <updated>Tue, 08 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/den-engelska-versionen-har-landat/</id>
        <content type="html"><![CDATA[<p>Det är en sanning med modifikation att allt innehåll på den här sidan är tillgängligt, men nu finns i alla fall möjligheten för mig att skriva på engelska.</p>
<p>Om allt fungerar som det ska så kommer innehållet för ditt valda språk att visas, startsidan kommer även att finnas på <code>/</code>, övriga sidor kommer att finnas på <code>/sv/</code> eller <code>/en/</code>. Så på grund av detta så kommer det förmodligen att bli 404:or. Vi får se hur Netlify hanterar mina omdirigeringar.</p>
<h2 id="hur-fungerar-det%3F" tabindex="-1">Hur fungerar det?</h2>
<p>Eleventy har stöd för att skapa flerspråkiga sidor och det är det jag har använt för att skapa en engelsk version av den här sidan. Om du är intresserad så går det att läsa mer på den <a href="https://www.11ty.dev/docs/i18n/" target="_blank" rel="noopener">officiella dokumentationen</a>. Men på en sida som den här som faktiskt växt en hel del (innehållsmässigt) sen jag startade så var det inte helt enkelt. Av den anledningen så letade jag runt lite efter material och hittade en bra guide på Lene Sailes blogg, <a href="https://www.lenesaile.com/en/blog/internationalization-with-eleventy-20-and-netlify/" target="_blank" rel="noopener">Internationalization with Eleventy 2.0 and Netlify</a>.</p>
<p>Systemet och hur Eleventy fungerar gör så att för de sidor och poster som finns på både språken så visar navigation, både i navigationen och i sidfoten, att det finns en engelsk/svensk version tillgänglig. I bakgrunden så betyder det att det finns en fil som heter samma i mappstrukturen.</p>
<pre class="language-plaintext"><code class="language-plaintext">src
├── en
│   ├── index.md
│   ├── posts
│   │   ├── 2024
            ├── den engelska versionen har landat.md
└── sv
    ├── index.md
    ├── posts
        ├── 2024
            ├── den engelska versionen har landat.md</code></pre>
<p>Sen skapas collections utifrån vilket språk som är det aktiva. Det gör att jag kan visa enbart de poster som är på det aktiva språket.</p>
<h2 id="inneh%C3%A5llet-och-%C3%B6vers%C3%A4ttningen" tabindex="-1">Innehållet och översättningen</h2>
<p>När det gäller innehållet så kommer det ofta vara en översättning gjord av en maskin, det är inget jag kommer att låtsas att jag har gjort. Men det betyder inte att jag inte kommer ändra i texten och redigera texten för att göra den mer läsbar. Med tanke på det så tänker jag att jag kommer ange källa för översättningen.</p>
<p>Det finns en viktig kvalite att behålla när en använder AI och det är en den personliga rösten. Det är något som väldigt lätt kan försvinna och det är inget AI kan skapa.</p>
<h2 id="%C3%A5terkoppling" tabindex="-1">Återkoppling</h2>
<p>Om du hittar något som inte stämmer eller om du har något att säga om översättningen så får du gärna kontakta mig. Jag är öppen för att ta emot feedback och för att förbättra innehållet.</p>
<h3>Kontakt</h3>
<form class="flow" name="contact" action="/sv/success" method="POST" netlify-honeypot="bot-field" data-netlify="true">
    <p class="hidden">
        <label>
            Om du är en människa så lämna detta fält tomt: <input name="bot-field" />
        </label>
    </p>
    <div>
        <label for="yourName">Namn</label>
        <input name="name" type="text" id="yourName" required="true">
    </div>
    <div>
      <label for="yourEmail">E-post (valfritt, endast om du vill ha ett svar)</label>
      <input name="email" type="email" id="yourEmail">
  </div>
    <div>
        <label for="message">Meddelande</label>
        <textarea name="message" id="message" rows="4" required="true"></textarea>
    </div>
    <button class="button" type="submit">Skicka</button>
</form>]]></content>
    </entry>
    
    
    <entry>
        <title>The English version has landed</title>
        <link href="https://jensa.dev/en/posts/the-english-version-has-landed/"/>
        <updated>Tue, 08 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/en/posts/the-english-version-has-landed/</id>
        <content type="html"><![CDATA[<p>It is a half-truth that all content on this page is available, but now I have the opportunity to write in English.</p>
<p>If everything works as it should, the content for your chosen language will be displayed. The homepage will also be available at <code>/</code>, while other pages will be available at <code>/sv/</code> or <code>/en/</code>. Because of this, there will probably be 404 errors. We’ll see how Netlify handles my redirects.</p>
<h2 id="how-does-it-work%3F" tabindex="-1">How does it work?</h2>
<p>Eleventy supports creating multilingual sites, and that’s what I’ve used to create an English version of this site. If you’re interested, you can read more in the <a href="https://www.11ty.dev/docs/i18n/" target="_blank" rel="noopener">official documentation</a>. However, on a site like this one, which has actually grown quite a bit (content-wise) since I started, it wasn’t entirely straightforward. For that reason, I looked around for material and found a good guide on Lene Saile’s blog, <a href="https://www.lenesaile.com/en/blog/internationalization-with-eleventy-20-and-netlify/" target="_blank" rel="noopener">Internationalization with Eleventy 2.0 and Netlify</a>.</p>
<p>This system with eleventy works so for pages and posts that exist in both languages, the navigation, both in the header and in the footer, shows that there is an English/Swedish version available. In the background this means that there is a file with the same name in the other language folder.</p>
<pre class="language-plaintext"><code class="language-plaintext">src
├── en
│   ├── index.md
│   ├── posts
│   │   ├── 2024
            ├── den engelska versionen har landat.md
└── sv
    ├── index.md
    ├── posts
        ├── 2024
            ├── den engelska versionen har landat.md</code></pre>
<p>Once this is set up, collections are created based on the active language. This allows me to display only the posts that are in the active language.</p>
<h2 id="content-and-translation" tabindex="-1">Content and translation</h2>
<p>For the content, it will often be a translation made by a machine, it is not something I will pretend that I have done. But that does not mean that I will not change the text and edit the text to make it more readable. With that in mind, I intend to provide the source of the translation.</p>
<p>When using AI to translate it is important to not loose your voice, and that is something I will try to keep in mind when editing the text.</p>
<h2 id="feedback" tabindex="-1">Feedback</h2>
<p>If you find something that is incorrect or if you have something to say about the translation, please feel free to contact me. I am open to receiving feedback and to improve the content.</p>
<h3>Contact</h3>
<form class="flow" name="contact" action="/en/success" method="POST" netlify-honeypot="bot-field" data-netlify="true">
    <p class="hidden">
        <label>
            If you are a human, ignore this field: <input name="bot-field" />
        </label>
    </p>
    <div>
        <label for="yourName">Name</label>
        <input name="name" type="text" id="yourName" required="true">
    </div>
    <div>
      <label for="yourEmail">Email (optional, only if you want a reply)</label>
      <input name="email" type="email" id="yourEmail">
  </div>
    <div>
        <label for="message">Message</label>
        <textarea name="message" id="message" rows="4" required="true"></textarea>
    </div>
    <button class="button" type="submit">Send</button>
</form>
<aside>
This translation is done in Visual Studio Code, with the help of GitHub Copilot and [Code spell checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker).
</aside>
]]></content>
    </entry>
    
    
    <entry>
        <title>Incremental spel med javascript</title>
        <link href="https://jensa.dev/sv/posts/incremental-spel-med-javascript/"/>
        <updated>Mon, 07 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/incremental-spel-med-javascript/</id>
        <content type="html"><![CDATA[<h2 id="vad-%C3%A4r-ett-incremental-spel%3F" tabindex="-1">Vad är ett incremental spel?</h2>
<p>Ett incremental spel (inkrementella, ökande, svårt att översätta), är ett spel där spelare gör små handlingar för att öka en siffra eller poäng. Det finns lite olika typer, clickers, idle och management. Det är en genre som är populär på webben och i mobila enheter. Allt eftersom spelaren ökar sin poäng så kan spelaren köpa uppgraderingar som ökar poängen automatiskt eller i större mängd.</p>
<h3 id="olika-typer" tabindex="-1">Olika typer</h3>
<ul>
<li>Inkrementella spel: Fokuserar på gradvis framsteg och ackumulering av resurser.</li>
<li>Idle-spel: Betonar automatisering och framsteg medan spelaren är borta.</li>
<li>Clicker-spel: Kräver aktivt klickande för att göra framsteg, särskilt i de tidiga stadierna.</li>
</ul>
<p>Som du ser så är det olika typer av spel med en gemensam grund.</p>
<h2 id="hur-fungerar-det-d%C3%A5%3F" tabindex="-1">Hur fungerar det då?</h2>
<p>Inkrementella spel har ett enkelt spelsystem som uppmuntrar spelare att fortsätta spela genom att erbjuda belöningar och engagerande mekanik. Några nyckelkomponenter i ett inkrementellt spel inkluderar:</p>
<ul>
<li>Spelloop: Kärnan i spelet som spelare upprepar (t.ex. klicka, tjäna, uppgradera).</li>
<li>Belöningar: Incitament som håller spelarna motiverade (t.ex. prestationer, nya funktioner).</li>
<li>Engagerande mekanik: Unika funktioner som skiljer spelet från andra (t.ex. storyelement, specialhändelser).</li>
</ul>
<h3 id="viktiga-fr%C3%A5gor" tabindex="-1">Viktiga frågor</h3>
<p>Som alla spel är det svåraste att göra det engagerande och roligt. Här är några viktiga frågor att ställa när du designar ett inkrementellt spel:</p>
<ul>
<li>Framsteg: Hur säkerställer spelet en känsla av framsteg?</li>
<li>Balans: Hur upprätthåller spelet en utmaning utan att bli frustrerande?</li>
<li>Feedback: Hur kommunicerar spelet framgång och framsteg till spelaren?</li>
</ul>
<h2 id="exempel-p%C3%A5-ett-inkrementellt-clicker-spel" tabindex="-1">Exempel på ett Inkrementellt Clicker-spel</h2>
<p class="important">Om du har svårt med att komma på ett spel så kan du använda mallen ovan som input för prompt till en generativ AI. Det kan hjälpa med kreativiteten och att komma igång. Fråga också efter flera förslag.</p>
<p>Här hittar du <a href="https://chatgpt.com/share/6703bf1f-9728-8002-aaed-78fead50ddc2" target="_blank" rel="noopener">min prompt och Chat-GPTs svar</a>.</p>
<p>En av fördelarna med att arbeta med AI på det här sättet är också att du kan fortsätta ställa frågor och utveckla idén. Kom ihåg att det är en AI tjänst och är du inte nöjd med svaret så kan du ställa om frågan eller be om fler förslag.</p>
<p>För den här texten så kör vi med iden från Chat-GPTs svar, ett cyberpunk clicker-spel.</p>
<h3 id="cyberpunk-hackersyndikat" tabindex="-1">Cyberpunk Hackersyndikat</h3>
<p>I en dystopisk framtid styr megakorporationer städerna och övervakar allt. Du leder ett underjordiskt hackersyndikat med ett mål: att ta tillbaka kontrollen. Genom att hacka företag och stjäla deras data bryter du ner systemet bit för bit. Men varje framsteg innebär större risker – avancerad säkerhet hotar din existens.</p>
<p><picture><source type="image/webp" srcset="/img/zz6VZ15thw-300.webp 300w, /img/zz6VZ15thw-600.webp 600w" sizes="100vw"><img alt="Adobe firefly illustrtaion av speliden" loading="lazy" decoding="async" src="/img/zz6VZ15thw-300.jpeg" width="600" height="342" srcset="/img/zz6VZ15thw-300.jpeg 300w, /img/zz6VZ15thw-600.jpeg 600w" sizes="100vw"></picture></p>
<p>Som mästare över stadens digitala underjord måste du balansera risk och belöning. Kan du krossa megakorporationernas grepp, eller förlorar du allt i jakten på digital makt?</p>
<p>Jag passade även på att be om hjälp med namn för spelet då Cyberpunk Hackersyndikat inte direkt rullar av tungan. Förslagen var sådär så vi kör med <strong>Nollskiftet</strong>.</p>
<h4 id="olika-typer%3A" tabindex="-1">Olika typer:</h4>
<ul>
<li>Inkrementellt spel: Spelaren samlar digitala resurser och hackar in i system för att tjäna pengar och kontrollera staden.</li>
<li>Idle-spel: Automatisera dina hackare och AI-program för att samla data och resurser medan du är borta.</li>
<li>Clicker-spel: Klicka för att hacka system och samla in data manuellt i de tidiga stadierna.</li>
</ul>
<h4 id="hur-fungerar-det-d%C3%A5%3F-1" tabindex="-1">Hur fungerar det då?</h4>
<ul>
<li>Spelloop: Klicka för att hacka in i system, stjäla data och resurser, och investera i kraftfullare hackningsverktyg och AI-botar.</li>
<li>Belöningar: Uppgradera dina hackverktyg och lås upp större mål, såsom multinationella företag och regeringssystem.</li>
<li>Engagerande mekanik: Fokusera på strategi genom att balansera risken för att bli upptäckt med potentiell belöning.</li>
</ul>
<h4 id="viktiga-fr%C3%A5gor%3A" tabindex="-1">Viktiga frågor:</h4>
<ul>
<li>Framsteg: Hackningsnivån ökar, och större och farligare system blir tillgängliga att hacka.</li>
<li>Balans: Spelaren måste balansera riskerna med att bli upptäckt mot de stora belöningarna från framgångsrika hack.</li>
<li>Feedback: Spännande grafisk feedback och ljud när ett system bryts ner och ett hack lyckas.</li>
</ul>
<h2 id="att-skapa-spelet" tabindex="-1">Att skapa spelet</h2>
<p>Nu har vi en idé att arbeta med. Så nu är det dags att sätta igång och skapa spelet. Vi kommer att använda oss av javascript, html och css för att skapa spelet.</p>
<h3 id="grundl%C3%A4ggande-struktur" tabindex="-1">Grundläggande struktur</h3>
<p>Vi börjar med att skapa en grundläggande struktur för spelet. Vi behöver en HTML-fil, en CSS-fil och en JavaScript-fil.</p>
<p>Du kan skapa filerna lokalt eller kopiera projektet på <a href="https://codepen.io/jensadev/pen/eYqzwxX" target="_blank" rel="noopener">Codepen</a>.</p>
<h4 id="html" tabindex="-1">HTML</h4>
<p>För att fokusera på det viktigaste så inkluderar jag inte den fullständiga strukturen för en webbsida. Vi behöver en container för spelet, en rubrik, en knapp för att hacka systemet och en räknare för stulen data.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>container<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>Nollskiftet<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Klicka för att hacka systemet och stjäla data!<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>hackButton<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Hacka!<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>Stulen Data: <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>dataStolen<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">></span></span></code></pre>
<h4 id="css" tabindex="-1">CSS</h4>
<p>Stilarna på spelet är väldigt viktigt, men det blir snabbt mycket kod. Här är en enkel stil för att testa. Vill du se den fullständiga stilmallen så finns den på <a href="https://codepen.io/jensadev/pen/eYqzwxX" target="_blank" rel="noopener">Codepen</a>.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span>
  <span class="token property">font-family</span><span class="token punctuation">:</span> sans-serif<span class="token punctuation">;</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 1.2rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.container</span> <span class="token punctuation">{</span>
  <span class="token property">width</span><span class="token punctuation">:</span> <span class="token function">min</span><span class="token punctuation">(</span>70ch<span class="token punctuation">,</span> 100% - 3rem<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token property">margin-inline</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">button</span> <span class="token punctuation">{</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 0.5em<span class="token punctuation">;</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 2rem<span class="token punctuation">;</span>
  <span class="token property">cursor</span><span class="token punctuation">:</span> pointer<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="javascript" tabindex="-1">JavaScript</h3>
<p>För att göra spelet interaktivt behöver vi JavaScript för att hantera klickhändelsen och uppdatera data. Här är en enkel JavaScript-kod för att räkna stulen data när spelaren klickar på knappen.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> hackButton <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#hackButton"</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> dataElement <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#dataStolen"</span><span class="token punctuation">)</span>

<span class="token keyword">let</span> dataStolen <span class="token operator">=</span> <span class="token number">0</span>

hackButton<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
  dataStolen <span class="token operator">+=</span> <span class="token number">1</span>
  dataElement<span class="token punctuation">.</span>textContent <span class="token operator">=</span> dataStolen
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Koden väljer element med querySelector och lägger till en händelselyssnare för klickhändelsen på knappen. När spelaren klickar på knappen ökar dataStolen-värdet med 1 och uppdaterar textinnehållet i dataElement.</p>
<h2 id="sammanfattning" tabindex="-1">Sammanfattning</h2>
<p>I den här texten har vi tittat på vad ett inkrementellt spel är och hur det fungerar. Vi har också skapat en grundläggande struktur för ett inkrementellt clicker-spel med</p>
<ul>
<li>HTML för att skapa strukturen för spelet.</li>
<li>CSS för att styla spelet och göra det visuellt tilltalande.</li>
<li>JavaScript för att skapa spelets logik och interaktivitet.</li>
</ul>
<p>I nästa del, [Incremental spel, game loop] kommer vi att titta på hur vi kan utöka spelet med fler funktioner och mekaniker för att göra det mer engagerande och roligt att spela.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Våga prova</title>
        <link href="https://jensa.dev/sv/posts/vaga-prova/"/>
        <updated>Tue, 01 Oct 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/vaga-prova/</id>
        <content type="html"><![CDATA[<p>Som inledningen och titeln antyder om så provar jag något, jag provar ett par fonter. Jag är konstant och pillrar i utformningen av den här sidan och alltför ofta hindrar det mig i skrivandet av innehåll. Men det är som det är.</p>
<p>Jag fick nyligen tips om ett par tjänster för att hitta och testa fonter. Det är alternativ till <a href="https://fonts.google.com/" target="_blank" rel="noopener">Google Fonts</a>, som får ses som den vanligaste tjänster för fonter. Oavsett vad man nu tycker om Google och deras tjänster så är det bra att ha alternativ.</p>
<p>Fonterna jag testar är från <a href="https://www.fontshare.com/" target="_blank" rel="noopener">Fontshare</a> och är en föreslagen <a href="https://www.fontshare.com/pairs" target="_blank" rel="noopener">pairing</a>, det är <a href="https://www.fontshare.com/fonts/bebas-neue" target="_blank" rel="noopener">Beubas Neue</a> och <a href="https://www.fontshare.com/fonts/nunito" target="_blank" rel="noopener">Nunito</a>. Förhoppnings är sidan fortfarande lättläst, har lite mer style och är framförallt roligare än <code>sans-serif</code>.</p>
<p>Nu kan jag vill inte säga att jag är helt färdig med att uppdatera all design och jag behöver nog skruva på en del, men det är en start. Just Beubas Neue behövde lite <code>letter-spacing</code> för att inte se för trång ut. Jag använde dessutom <code>rem</code> som mått då <code>em</code> blev för stort.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">h1, h2, h3, h4</span> <span class="token punctuation">{</span>
  <span class="token property">letter-spacing</span><span class="token punctuation">:</span> 0.1rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="alternativen" tabindex="-1">Alternativen</h2>
<p>Här är länkarna.</p>
<ul>
<li><a href="https://" target="_blank" rel="noopener">Fontshare</a></li>
<li><a href="https://www.collletttivo.it/" target="_blank" rel="noopener">collletttivo</a></li>
<li><a href="https://uncut.wtf/" target="_blank" rel="noopener">Uncut</a>.</li>
</ul>
<p>För de tidigare nämnda Google Fonts finns det en tjänst som heter <a href="https://fontjoy.com/" target="_blank" rel="noopener">Fontjoy</a> som hjälper till att hitta “bra” kombinationer.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Ordlista</title>
        <link href="https://jensa.dev/sv/posts/ordlista/"/>
        <updated>Tue, 10 Sep 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/ordlista/</id>
        <content type="html"><![CDATA[<p>I kursen webbserverprogramering så är det väldigt mycket nya ord och begrepp som dyker upp. Så under en lektion började vi tillsammans att skapa en ordlista. Här är den.</p>
<p>Listan får sägas är en work in progress och kommer att uppdateras. Men att jag skriver den betyder inte att du inte ska göra det. Skriv ner ord och förklaringar som du inte förstår. Det är en del av att lära sig.</p>
<h2 id="allm%C3%A4nt" tabindex="-1">Allmänt</h2>
<p>Inte helt lätt, men här hamnar en del ord som dyker upp i undervisningen.</p>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förkortning</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>WSL</td>
<td>Windows Subsystem for Linux</td>
<td>Ett sätt att köra Linux på Windows</td>
</tr>
<tr>
<td>CLI</td>
<td>Command Line Interface</td>
<td>Ett sätt att interagera med datorn via terminalen</td>
</tr>
<tr>
<td>Ubuntu</td>
<td></td>
<td>En distribution av Linux</td>
</tr>
<tr>
<td>Terminal</td>
<td></td>
<td>Ett fönster där du kan skriva kommandon</td>
</tr>
<tr>
<td>Git</td>
<td></td>
<td>Versionshanteringssystem</td>
</tr>
<tr>
<td>GitHub</td>
<td></td>
<td>Plattform för att lagra och dela kod</td>
</tr>
</tbody>
</table>
<h2 id="linux-kommandon" tabindex="-1">Linux kommandon</h2>
<p>Vi kör WSL i undervisningen och då är det bra att känna till några grundläggande kommandon.</p>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>ls</td>
<td>Listar filer och mappar</td>
</tr>
<tr>
<td>cd</td>
<td>Byter mapp</td>
</tr>
<tr>
<td>pwd</td>
<td>Visar vilken mapp du är i</td>
</tr>
<tr>
<td>mkdir</td>
<td>Skapar en mapp</td>
</tr>
<tr>
<td>touch</td>
<td>Skapar en fil</td>
</tr>
<tr>
<td>rm</td>
<td>Tar bort en fil</td>
</tr>
<tr>
<td>cp</td>
<td>Kopierar en fil</td>
</tr>
<tr>
<td>mv</td>
<td>Flyttar en fil</td>
</tr>
<tr>
<td>cat</td>
<td>Visar innehållet i en fil</td>
</tr>
<tr>
<td>nano</td>
<td>Öppnar en texteditor</td>
</tr>
<tr>
<td>sudo</td>
<td>Kör kommandot som administratör</td>
</tr>
<tr>
<td>kill</td>
<td>Avslutar ett program</td>
</tr>
<tr>
<td>killall</td>
<td>Avslutar alla instanser av ett program</td>
</tr>
<tr>
<td>ps</td>
<td>Visar processer , auxf för allt</td>
</tr>
<tr>
<td>top</td>
<td>Visar processer i realtid</td>
</tr>
</tbody>
</table>
<h2 id="webbserver" tabindex="-1">Webbserver</h2>
<p>Här hamnar en del ord kopplade till webbserver och ganska många protokoll.</p>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förkortning</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTTP</td>
<td>HyperText Transfer Protocol</td>
<td>Protokoll för att överföra data över internet</td>
</tr>
<tr>
<td>HTTPS</td>
<td>HyperText Transfer Protocol Secure</td>
<td>Säker version av HTTP</td>
</tr>
<tr>
<td>TCP</td>
<td>Transmission Control Protocol</td>
<td>Protokoll för att överföra data över internet. Otroligt omständigt och inte så effektivt. Använder handshakes osv.</td>
</tr>
<tr>
<td>IP</td>
<td>Internet Protocol</td>
<td>Protokoll för att överföra data över internet</td>
</tr>
<tr>
<td>UDP</td>
<td>User Datagram Protocol</td>
<td>Protokoll för att överföra data över internet. Till skillnad från TCP skickar det bara data, hanterar inte eventuella fel.</td>
</tr>
<tr>
<td>DNS</td>
<td>Domain Name System</td>
<td>Protokoll för att översätta domännamn till IP-adresser</td>
</tr>
<tr>
<td>URL</td>
<td>Uniform Resource Locator</td>
<td>Adress till en resurs på internet</td>
</tr>
<tr>
<td>REST</td>
<td>Representational State Transfer</td>
<td>Arkitektur för att bygga webbtjänster</td>
</tr>
</tbody>
</table>
<h2 id="express" tabindex="-1">Express</h2>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förkortning</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>Express</td>
<td></td>
<td>Ett ramverk för att bygga webbapplikationer i Node.js</td>
</tr>
<tr>
<td>Middleware</td>
<td></td>
<td>Funktioner som körs innan en route</td>
</tr>
<tr>
<td>Route</td>
<td></td>
<td>En endpoint i en webbapplikation</td>
</tr>
<tr>
<td>View</td>
<td></td>
<td>En representation av en webbsida</td>
</tr>
<tr>
<td>Nunjucks</td>
<td></td>
<td>Ett templating-språk för att skapa dynamiska webbsidor</td>
</tr>
<tr>
<td>Static</td>
<td></td>
<td>Statiska filer som bilder, css och javascript, sparas i /public</td>
</tr>
<tr>
<td>GET</td>
<td></td>
<td>En HTTP-metod för att hämta data</td>
</tr>
<tr>
<td>POST</td>
<td></td>
<td>En HTTP-metod för att skicka data</td>
</tr>
<tr>
<td>query</td>
<td></td>
<td>En del av URL:en som innehåller data, skriv med ?v=id</td>
</tr>
<tr>
<td>params</td>
<td></td>
<td>En del av URL:en som innehåller data, skriv med /:id</td>
</tr>
</tbody>
</table>
<h2 id="node" tabindex="-1">Node</h2>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förkortning</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>node</td>
<td></td>
<td>JavaScript runtime, använder chrome v8 för att köra javascript</td>
</tr>
<tr>
<td>nvm</td>
<td>Node Version Manager</td>
<td>Verktyg för att hantera olika versioner av Node.js</td>
</tr>
<tr>
<td>npm</td>
<td>Node Package Manager</td>
<td>Pakethanterare för Node.js</td>
</tr>
<tr>
<td>package.json</td>
<td></td>
<td>Fil som innehåller metadata om ett npm-paket</td>
</tr>
</tbody>
</table>
<h2 id="s%C3%A4kerhet" tabindex="-1">Säkerhet</h2>
<table>
<thead>
<tr>
<th>Ord</th>
<th>Förkortning</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td>XSS</td>
<td>Cross-Site Scripting</td>
<td>En attack där en angripare injicerar skadlig kod i en webbsida</td>
</tr>
<tr>
<td>Stored XSS</td>
<td></td>
<td>En typ av XSS-attack där skadlig kod lagras på servern och skickas till alla användare</td>
</tr>
<tr>
<td>Reflected XSS</td>
<td></td>
<td>En typ av XSS-attack där skadlig kod skickas till en användare via en länk</td>
</tr>
<tr>
<td>Self XSS</td>
<td></td>
<td>En typ av XSS-attack där en användare injicerar skadlig kod i sin egen webbläsare</td>
</tr>
<tr>
<td>CSRF</td>
<td>Cross-Site Request Forgery</td>
<td>En attack där en angripare får en användare att utföra en oönskad handling på en webbplats där användaren är inloggad</td>
</tr>
<tr>
<td>SQL Injection</td>
<td></td>
<td>En attack där en angripare injicerar skadlig SQL-kod i en webbapplikation</td>
</tr>
</tbody>
</table>
<h2 id="viktiga-vscode-shortcuts" tabindex="-1">Viktiga vscode shortcuts</h2>
<table>
<thead>
<tr>
<th>Kombination</th>
<th>Förklaring</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Ctrl + Shift + P</code></td>
<td>Öppna kommandoprompten</td>
</tr>
<tr>
<td><code>Ctrl + P</code></td>
<td>Sök efter fil</td>
</tr>
<tr>
<td><code>Shift + Alt + F</code></td>
<td>Formatera fil</td>
</tr>
</tbody>
</table>
]]></content>
    </entry>
    
    
    <entry>
        <title>Kom igång med express</title>
        <link href="https://jensa.dev/sv/posts/kom-igang-med-express/"/>
        <updated>Tue, 10 Sep 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/kom-igang-med-express/</id>
        <content type="html"><![CDATA[<p>Det här är en kort introduktion till det allra mest grundläggande i kursen webbserverprogramering. Där använder vi <code>javascript</code> och <code>Node.js</code> som språk och miljö, med paketet <code>Express</code> för att skapa en server. Här är en snabbstart för att komma igång.</p>
<p>Den här guiden förutsätter att du har installerat <code>Node.js</code> och <code>npm</code>. Se instruktioner från posten <a href="/sv/posts/webbserver-programmering/">webbserverprogrammering</a>.</p>
<h2 id="code-mapp" tabindex="-1">Code mapp</h2>
<p>Jag tycker det är “bäst” och enklast att ha en mapp för all kod. Jag kallar den <code>code</code> och den ligger i hemmappen. För att komma till din hemmapp så kan du skriva <code>cd</code> i terminalen.</p>
<pre class="language-bash"><code class="language-bash"><span class="token builtin class-name">cd</span>
<span class="token function">mkdir</span> code</code></pre>
<h2 id="server-setup" tabindex="-1">Server setup</h2>
<p>För att skapa en server kommer vi att skapa en mapp för projektet, detta för att samla allt på ett organiserat och strukturerat sätt. Att vi sparar allt i en mapp låter oss också använda mappen som en bas för ett Git repo.</p>
<p>Följande kommandon skapar mappen, initierar ett npm-projekt, installerar <code>express</code> och <code>nodemon</code> samt skapar en <code>.gitignore</code> fil.</p>
<pre class="language-bash"><code class="language-bash"><span class="token builtin class-name">cd</span>
<span class="token builtin class-name">cd</span> code
<span class="token function">mkdir</span> test-server
<span class="token builtin class-name">cd</span> test-server
<span class="token function">touch</span> server.js
<span class="token function">npm</span> init <span class="token parameter variable">-y</span>
<span class="token function">npm</span> i express
<span class="token function">npm</span> i nodemon --save-dev
<span class="token builtin class-name">echo</span> <span class="token string">"node_modules"</span> <span class="token operator">></span> .gitignore</code></pre>
<ul>
<li><code>cd</code> - Byter mapp till den angivna mappen.</li>
<li><code>mkdir</code> - Skapar en mapp med det angivna namnet.</li>
<li><code>touch</code> - Skapar en fil med det angivna namnet.</li>
<li><code>npm init -y</code> - Initierar ett npm-projekt med standardvärden.</li>
<li><code>npm i</code> - Installerar paket med npm.</li>
</ul>
<h3 id="esm" tabindex="-1">ESM</h3>
<p>ESM är en förkortning för ECMAScript Modules och är en del av ES6. Det är en standard för att importera och exportera moduler i JavaScript. Vi vill skriva server med ESM och inte CommonJS. Anledningen till att vi skriver server med ESM är för  att det är den moderna standarden för att importera och exportera moduler i JavaScript. Vi framtidssäkrar vår kod med detta.<br>
För att kunna köra koden med ESM i <code>node</code>, behöver vi ange att typen är en module i <code>package.json</code>. <code>package.json</code> är en fil som innehåller metadata om projektet och vilka paket projektet behöver för att köras.</p>
<p>Lägg till följande rad i <code>package.json</code>.</p>
<pre class="language-json"><code class="language-json"><span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"module"</span><span class="token punctuation">,</span></code></pre>
<p>För att starta servern behöver vi även skapa ett start script i <code>package.json</code>.</p>
<pre class="language-json"><code class="language-json"><span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"dev"</span><span class="token operator">:</span> <span class="token string">"nodemon server.js"</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre>
<p>För att ha något att starta så lägger vi till följande kod i <code>server.js</code>.</p>
<pre class="language-javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Sedan startar vi server i terminalen med <code>npm run dev</code>. Om det fungerar så kommer du att se <code>Hello world</code> i terminalen.</p>
<h2 id="express" tabindex="-1">Express</h2>
<p><strong>Se till att du kan starta filen med <code>npm run dev</code> innan du går vidare. Det är viktigt att du alltid kan starta och köra ditt projekt medans du arbetar.</strong></p>
<p>Nu när vi har en server som startar så kan vi börja med att använda <code>Express</code>. Vi börjar med att importera <code>Express</code> och skapa en instans av det. Instansen behövs för att skapa routes och starta servern.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> express <span class="token keyword">from</span> <span class="token string">'express'</span>

<span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre>
<p>För att starta servern så behöver vi lyssna på en port. Vi kan använda <code>app.listen</code> för att göra detta.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token constant">PORT</span> <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">PORT</span> <span class="token operator">||</span> <span class="token number">3000</span>
app<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token constant">PORT</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Server is running on http://localhost:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">PORT</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Om du startar servern nu så kommer du att se att den skriver meddelandet i terminalen, att den startat och körs på localhost:3000. Surfa nu till <code>http://localhost:3000</code> i din webbläsare så kommer du att se att den inte svarar. Detta beror på att vi inte har någon route.</p>
<h3 id="routes" tabindex="-1">Routes</h3>
<p>En route är en URL som servern svarar på. För att skapa en route så behöver vi en metod och en URL. Metoden för att svara på en <code>GET</code> request är <code>app.get</code>.</p>
<p>Redigera <code>server.js</code> och lägg till följande kod innan <code>app.listen</code>.</p>
<pre class="language-javascript"><code class="language-javascript">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">'Hello world'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Om du startar servern nu och går till <code>http://localhost:3000</code> så kommer du att se att den svarar med <code>Hello world</code>. <code>res.send</code> skickar en respons till klienten.</p>
<h2 id="templates-med-nunjucks" tabindex="-1">Templates med nunjucks</h2>
<p>Templates används för att skapa dynamiskt innehåll på servern.<br>
För att skapa templates så använder vi språket <code>nunjucks</code>. Ett template språk låter oss skapa html dynamisk på servern. Vi kan då använda oss av variabler och programmeringslogik för att anpassa och generera html för sidorna.</p>
<p>Vi börjar med att installera paketet <code>nunjucks</code> med npm.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i nunjucks</code></pre>
<p>För att använda <code>nunjucks</code> så behöver vi konfigurera den. Konfigurationen gör du i <code>server.js</code>, lägg till detta efter raden <code>const app = express()</code>, det är viktigt eftersom nunjucks behöver en instans av express för att fungera.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> nunjucks <span class="token keyword">from</span> <span class="token string">'nunjucks'</span>

<span class="token operator">...</span>

nunjucks<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token string">'views'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">autoescape</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token literal-property property">express</span><span class="token operator">:</span> app
<span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<p>Vi skapar sedan en mapp <code>views</code> där vi lägger våra templates. Skapa mappen med följande kommando.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">mkdir</span> views</code></pre>
<p>I mappen <code>views</code> skapar vi två filer <code>index.njk</code>och <code>layout.njk</code>. I <code>layout.njk</code> skapar vi en grundstruktur för sidan.</p>
<pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sv<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>{{ title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
  {% block content %}
  {% endblock %}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>I <code>index.njk</code> skapar vi en enkel sida som använder layouten.</p>
<pre class="language-html"><code class="language-html">{% extends "layout.njk" %}

{% block content %}
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>{{ title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span>{{ message }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span>
{% endblock %}</code></pre>
<p>I <code>server.js</code> så skapar vi en route som renderar <code>index.njk</code>. Detta gör vi genom att använda <code>res.render</code>. Render tar två argument, första är filnamnet på templaten och det andra är ett objekt med variabler som skickas till templaten.</p>
<pre class="language-javascript"><code class="language-javascript">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    res<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string">'index.njk'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'Hello world'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">message</span><span class="token operator">:</span> <span class="token string">'This is a message'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<p>Om du startar servern nu och går till <code>http://localhost:3000</code> så kommer du att se att den svarar med en html-sida.</p>
<h2 id="statiska-filer" tabindex="-1">Statiska filer</h2>
<p>För att servern ska kunna skicka statiska filer såsom bilder, css och javascript så kan vi använda <code>express.static</code>. Vi kan använda <code>express.static</code> för att skapa en route som pekar på en mapp.</p>
<p>Vi skapar en mapp <code>public</code> där vi lägger våra statiska filer. Skapa mappen med följande kommando.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">mkdir</span> public</code></pre>
<p>I mappen <code>public</code> skapar vi en mapp <code>css</code> och en fil <code>style.css</code>. I <code>style.css</code> skriver vi lite css.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span>
    <span class="token property">font-family</span><span class="token punctuation">:</span> sans-serif<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 1.2rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>I <code>server.js</code> så skapar vi en route som pekar på mappen <code>public</code>.</p>
<pre class="language-javascript"><code class="language-javascript">app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>express<span class="token punctuation">.</span><span class="token function">static</span><span class="token punctuation">(</span><span class="token string">'public'</span><span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre>
<p>Om du startar servern nu och går till <code>http://localhost:3000/css/style.css</code> så kommer du att se att den svarar med css-filen.<br>
Vi kan nu använda css-filen i våra templates, redigera <code>layout.njk</code> och lägg till följande rad i sidans <code>&lt;head&gt;</code>.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/css/style.css<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></code></pre>
<h3 id="middleware" tabindex="-1">Middleware</h3>
<p>Middleware är funktioner som körs innan en route. Vi kan använda middleware för att logga information om en request.</p>
<pre class="language-javascript"><code class="language-javascript">app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res<span class="token punctuation">,</span> next</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>method<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>req<span class="token punctuation">.</span>url<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Vi kan även använda detta för att skapa en 404-sida. Lägg till följande kod efter alla routes.</p>
<pre class="language-javascript"><code class="language-javascript">app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    res<span class="token punctuation">.</span><span class="token function">status</span><span class="token punctuation">(</span><span class="token number">404</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">'404 - Not found'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<h3 id="hela-server.js" tabindex="-1">Hela server.js</h3>
<p>Den färdiga koden ser ut så här. Den förutsätter att du skapar <code>views</code> osv.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> express <span class="token keyword">from</span> <span class="token string">'express'</span>
<span class="token keyword">import</span> nunjucks <span class="token keyword">from</span> <span class="token string">'nunjucks'</span>

<span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>express<span class="token punctuation">.</span><span class="token function">static</span><span class="token punctuation">(</span><span class="token string">'public'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

nunjucks<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token string">'views'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">autoescape</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token literal-property property">express</span><span class="token operator">:</span> app
<span class="token punctuation">}</span><span class="token punctuation">)</span>

app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    res<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string">'index.njk'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'Hello world'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">message</span><span class="token operator">:</span> <span class="token string">'This is a message'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

app<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span> res</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    res<span class="token punctuation">.</span><span class="token function">status</span><span class="token punctuation">(</span><span class="token number">404</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">'404 - Not found'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token constant">PORT</span> <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">PORT</span> <span class="token operator">||</span> <span class="token number">3000</span>
app<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token constant">PORT</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Server is running on http://localhost:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token constant">PORT</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>Detta är en snabbstart för att komma igång med <code>Node.js</code> och <code>Express</code>. Det finns mycket mer att lära och utforska. Jag rekommenderar att du kollar in <a href="https://expressjs.com/" target="_blank" rel="noopener">Express dokumentation</a> och <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks dokumentation</a> för att lära dig mer.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Containers</title>
        <link href="https://jensa.dev/sv/posts/containers/"/>
        <updated>Mon, 02 Sep 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/containers/</id>
        <content type="html"><![CDATA[<p>Containers har funnits i olika former på webben i evigheter, men deras funktion och användning har varierat över tid. När jag tittade tillbaka på en webbsida jag kodade <time datetime="1999-01-01">1999</time>, så var innehållet i en container. Den containern var förvisso en <code>&lt;div&gt;</code> med <code>align=&quot;center&quot;</code> som innehöll ett <code>&lt;center&gt;</code>-element som i sin tur innehöll ett table med <code>width=&quot;800px&quot;</code>, men det tjänade samma syfte. Tack och lov har mycket förändrats sedan dess!</p>
<p>Syftet med en container, eller med en <code>.container</code>-klass är att kunna justera och placera innehåll på en webbplats. Innehållet ska med fördel då även anpassa sig efter skärmens storlek (ett måste idag).</p>
<p>Om vi öppnar utvecklar-verktygen och aktiverar grid-linjer så ser vi dels de linjer som sidans innehåll anpassar sig efter. Vi kan även se måtten för padding och margin för det valda elementet (finns under computed).</p>
<p><picture><source type="image/webp" srcset="/img/_Knlj8yNkB-300.webp 300w, /img/_Knlj8yNkB-600.webp 600w, /img/_Knlj8yNkB-900.webp 900w" sizes="100vw"><img alt="Screenshot av containers på den här webbplatsen" loading="lazy" decoding="async" src="/img/_Knlj8yNkB-300.jpeg" width="900" height="442" srcset="/img/_Knlj8yNkB-300.jpeg 300w, /img/_Knlj8yNkB-600.jpeg 600w, /img/_Knlj8yNkB-900.jpeg 900w" sizes="100vw"></picture></p>
<h2 id="ord-och-begrepp" tabindex="-1">Ord och begrepp</h2>
<p>Ord är viktiga och ibland kallas även containers på webben för wrappers. Det är inte riktigt samma sak, men de används ibland synonymt. En container är en behållare för innehåll, medan en wrapper omsluter innehållet. Det är upp till dig att välja den semantik som passar ditt arbete bäst</p>
<h2 id="exempel" tabindex="-1">Exempel</h2>
<p>Jag har skapat några exempel på CodePen för att illustrera olika containers. Jag har använt dem i olika projekt, och de har tjänat mig väl. <code>.container</code>-klassens utveckling har följt med nya möjligheter i CSS och blir bara bättre och bättre.</p>
<div class="feature">
<p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="rNEqLEQ" data-user="jensadev" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jensadev/pen/rNEqLEQ">
  Containers</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<p>Här är ett exempel på en uppdaterad container från <a href="https://smolcss.dev/#smol-container" target="_blank" rel="noopener">SmolCSS.dev</a>, den känns igen från min länkade codepen ovan.</p>
<h2 id="den-h%C3%A4r-sidan%2C-just-nu" tabindex="-1">Den här sidan, just nu</h2>
<p>I den nuvarande iterationen av den här webbplatsen, 2024, valde jag att testa en ny teknik för att skapa containers. Tidigare har jag experimenterat med olika metoder för att återskapa bleed-effekter på sidan. Bleed kommer från tryckvärlden och innebär att innehållet går ut över sidans kanter. Dessa layouteffekter var jag inte nöjd med och tyckte inte att de fungerade bra.</p>
<p>Så det du nu ser är ett helt annat sätt att skapa containers och det är med namngivna grid-areas.</p>
<h3 id="inspiration" tabindex="-1">Inspiration</h3>
<p>Koden och inspirationen till detta kommer från en video av Kevin Powell där han visar ett alternativ till den klassiska container. Det gjorde mig nyfiken att testa.</p>
<div class="feature youtube-embed">
    <iframe 
        src="https://www.youtube-nocookie.com/embed/c13gpBrnGEw"
        title="YouTube video player"
        frameborder="0"
        allowfullscreen>
    </iframe>
    </div>
<p>Ursprunget till detta kommer från Ryan Mulligan och här kan du läsa hans artikel om <a href="https://ryanmulligan.dev/blog/layout-breakouts/" target="_blank" rel="noopener">Layout breakouts with css grid</a>.</p>
<h2 id="vad-ska-du-anv%C3%A4nda" tabindex="-1">Vad ska du använda</h2>
<p>Det beror på dina behov. I mitt fall önskade jag extra kontroll, men insåg att jag var fast i en struktur skapad utifrån en klassisk container-klass. För att få till funktionen fick jag skriva om en hel del HTML och tänka om. Resultatet är inte riktigt där ännu, men det är som alltid en work in progress.</p>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>Som vanligt leder upptäckten av ny teknik till en redesigna av den här webbplatsen… Verkar rimligt, kan till och med vara sidans egentliga syfte.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>2024, redesign</title>
        <link href="https://jensa.dev/sv/posts/2024-redesign/"/>
        <updated>Thu, 25 Apr 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/2024-redesign/</id>
        <content type="html"><![CDATA[<p>Som titeln och inledningen antyder och som du förmodligen ser så har jag gjort en redesign av sidan.</p>
<p>Jag var aldrig riktigt nöjd med version 3 av sidan, den kändes mörk och ganska eländig. Det är färger jag gillar, men för syftet, innehållet och vad det används till så passade det inte. Rent layoutmässigt så är jag ganska nöjd och kommer nog fortsätta vara det.</p>
<p>Sidans huvudsyfte är ändå att samla ihop det material jag skapat och publicerat för jobbet och presentera det i ett läsbart format för mina elever. De är ändå de som är mina huvudsakliga besökare. Övrig funktion är bonus.</p>
<h2 id="grafiskt" tabindex="-1">Grafiskt</h2>
<p>För utseendet, eller designen av sidan så är det inga större förändringar. Jag har joxat med fonter, storlek och lite färg, men på det stora hela är det samma. Jag har ändrat i hur listan över poster ser ut och skruvat lite i layouten, men det är mer ett resultat av teknik än design.</p>
<h3 id="uppdatering" tabindex="-1">Uppdatering</h3>
<p>Jag har nu lagt till möjligheten att använda cover bilder för poster. Det är något som länge varit på TODO listan och nu finns det på plats. Bilderna är i form av bakgrunder i sidhuvudet och de fungerar förhoppningsvis bra på alla enheter och med tillräcklig kontrast.</p>
<p>Själva bilderna och vad de föreställer, det är lite slumpat. Hittills är det en del blommor och abstrakta grunkor. Av någon anledning så tyckte Firefly att det passade med blommor och webbservrar när jag började generera. Jag har använt mig av <a href="https://firefly.adobe.com/" target="_blank" rel="noopener">Adobe Firefly</a> för att skapa dem. Det är AI och det är vad det är, jag gör inget anspråk på att vara konstnär.</p>
<h2 id="css" tabindex="-1">css</h2>
<p>En ganska stor förändring är att jag har slopat sass och istället bara skriver css. Med de förändringar som skett det senaste året med css så känns det som att jag inte behöver sass. Detta har även medfört att jag försökt rensa ut css som är onödig eller överflödig och i många fall även onödigt komplicerad.</p>
<blockquote>
<p>Enkelt och tillgängligt.</p>
<p>Jens</p>
</blockquote>
<p>Sen finns det en del kvar att göra i frågan om att skriva css och städa, men det kommer.</p>
<h3 id="containers-och-wrappers" tabindex="-1">Containers och wrappers</h3>
<p>För den här versionen av sidan och layouten så ville jag testa ett annat sätt att skriva containers, eller snarare inte använda den vanliga containern. Ryan Mulligan är en av de som skrivit om detta på sin blogg <a href="https://ryanmulligan.dev/blog/layout-breakouts/" target="_blank" rel="noopener">Layout Breakouts with CSS Grid</a>.</p>
<p>Jag tycker hittills att system fungerar bra och är intuitivt att använda. Sen kan jag uppleva att det sätt som jag strukturerat html på och skrivit css inte riktigt är anpassat för detta, men jag tänker att det är en del av processen att testa och lära sig.</p>
<p>Jag skriver mer om detta här, <a href="/posts/containers-och-wrappers">Containers och wrappers</a>.</p>
<h3 id="dark-mode-och-light-mode" tabindex="-1">Dark mode och light mode</h3>
<p>Nu är det möjligt att välja mellan dark mode och light mode igen. Det finns en knapp i navigationen, men den byter också automatisk beroende på din system-inställning.</p>
<h3 id="f%C3%A4rger" tabindex="-1">Färger</h3>
<p>Min ärkefiende, färger. Jag är aldrig nöjd och tycker aldrig att jag lyckas. Nu ville jag ha färger som skulle symbolisera teknik, nyfikenhet och att lära sig. Istället blev det rött och svart, anarki.</p>
<ul class="swatches">
  <li class="dark">dark</li>
  <li class="light">light</li>
  <li class="primary">primary</li>
  <li class="secondary">secondary</li>
</ul>
<h2 id="tekniskt" tabindex="-1">Tekniskt</h2>
<p>Lite mera javascript har dykt upp på sidan i form av ett sökfält och switchern för dark mode och light mode. Du kan testa sökfunktionen genom knappen i navigationen eller genom att tryck <code>ctrl+k</code> eller <code>cmd+k</code>.</p>
<p>Själva sökfunktionen i sig använder sig av <a href="https://www.npmjs.com/package/elasticlunr" target="_blank" rel="noopener">Elasticlunr</a> och den letar i en json fil som skapas utifrån 11tys collections. Koden är inget nytt och kommer från någon tutorial jag läste när jag skapade <a href="/projekt/tema-omrade-del/">TOD-projektet</a>.</p>
<h3 id="css-1" tabindex="-1">css</h3>
<p>Eftersom jag bytt från sass till css så vart jag tvungen att uppdatera arbetsflödet lite. Jag tittade på några olika lösningar men valda att använda <a href="https://www.npmjs.com/package/@11tyrocks/eleventy-plugin-lightningcss" target="_blank" rel="noopener">Eleventy Plugin: LightningCSS</a>. Det var enklast och gjorde det som jag önskade.</p>
<p>En senare fråga blir att eventuellt inlina css för att få sidan att ladda snabbare. Men jag tror det får sitta ihop med lite rensning av npm-paket och annat då post-css ligger kvar och skräpar.</p>
<h3 id="%E2%80%A6minuters-l%C3%A4sning" tabindex="-1">…minuters läsning</h3>
<p>Jag installerade <a href="https://www.npmjs.com/package/@11tyrocks/eleventy-plugin-emoji-readtime" target="_blank" rel="noopener">Eleventy Plugin: Emoji Read Time</a> för att få en uppskattning på hur lång tid det tar att läsa en post. Jag kom senare på att jag redan hade kod för detta i min helper.</p>
<h2 id="lighthouse" tabindex="-1">Lighthouse</h2>
<p>Det viktigate eller hur? Kanske inte men det ser bra ut. Tillgängligheten är något som jag inte vill tumma på, sidan är för alla och ska fungera för alla.</p>
<p>Det som finns kvar att göra är PWA delen. Sidan kanske inte behöver installeras, det är ingen funktion jag önskar. Men att den ska fungera offline är praktiskt.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>CRUD</title>
        <link href="https://jensa.dev/sv/posts/crud/"/>
        <updated>Thu, 29 Feb 2024 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/crud/</id>
        <content type="html"><![CDATA[<p>En kort post med lite material för kursen Webbserverprogrammering 1. Jag har tidigare gjort en video-serie om en filmdatabas som ligger på youtube, men den kändes lite utdaterad (jag har lärt mig nya saker och arbetar lite annorlunda).</p>
<p>Så här kommer en uppdaterad guide genom CRUD och REST med kommentarer. Jag försöker förklara hur jag tänkt samtidigt som jag kodat för att du ska få en förståelse för varför vi gör, inte bara hur.</p>
<p>Del 1-10 handlar om Read och Create med säkerhet i sista delen. Del 11-15 behandlar Update och Delete och REST.</p>
<p>Du hittar en <a href="https://youtube.com/playlist?list=PLgGdkZQ59lsX35naWFDG6MKJbbHiFcX9F&amp;si=OlfSyROwwMIg3fRm" target="_blank" rel="noopener">playlist</a> med allt på youtube och här är första delen:</p>
<div class="feature youtube-embed">
    <iframe 
        src="https://www.youtube-nocookie.com/embed/xb6eNuyUe2I"
        title="YouTube video player"
        frameborder="0"
        allowfullscreen>
    </iframe>
    </div>
<p>Koden finns som vanligt på GitHub, <a href="https://github.com/jensadev/wsp1-crud" target="_blank" rel="noopener">wsp1-crud</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Textäventyr, struktur och javascript</title>
        <link href="https://jensa.dev/sv/posts/textaventyr-struktur-och-javascript/"/>
        <updated>Thu, 28 Sep 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/textaventyr-struktur-och-javascript/</id>
        <content type="html"><![CDATA[<p>I den här texten kommer jag dock fokusera på det förstnämnda, ett spel i textform, och framförallt på hur det kan användas för att arbeta med grunderna i javascript.</p>
<h2 id="vad-%C3%A4r-ett-text%C3%A4ventyr%3F" tabindex="-1">Vad är ett textäventyr?</h2>
<p>Ett textäventyr är ett spel där du får en beskrivning av en situation och sedan får du välja vad du vill göra. Beroende på dina val så kan du hamna i nya situationer och så fortsätter berättelsen. Det som skiljer textäventyret från en bok är att händelserna inte är linjära, handlingen är inte förutbestämd. Det är du som spelare som styr handlingen. Det kan liknas vid ett träd där varje val du gör leder till en ny situation.</p>
<p>När jag var en liten, liten, parvel så spelade jag en del textäventyr i bokform, det kallades för <a href="https://sv.wikipedia.org/wiki/Solo%C3%A4ventyr" target="_blank" rel="noopener">soloäventyr</a> eller <a href="https://en.wikipedia.org/wiki/Choose_Your_Own_Adventure" target="_blank" rel="noopener">Choose Your Own Adventure</a> på engelska. Det var en bok där du läste en beskrivning av en situation och sedan fick du välja vad du ville göra. Beroende på ditt val så fick du hoppa till en ny sida i boken och läsa en ny beskrivning av en situation. Fler av böckerna jag läste var i serien om <a href="http://www.ensamma-vargen.se/" target="_blank" rel="noopener">Ensamma vargen</a>, en fantasyserie där du var hjälten.</p>
<h2 id="men-javascript-d%C3%A5" tabindex="-1">Men javascript då</h2>
<p>Premissen för denna text är kopplingen till kod och javascript, så nog om böcker. Textäventyret lämpar sig väl för denna form av koduppgiften tycker jag eftersom den ger möjlighet att utforska flera viktiga koncept.</p>
<p>Ett linjärt äventyr behöver i sig inte så mycket kod, du läser en linjär berättelse just nu (kanske en kan argumentera). Men när läsaren presenteras val och dessa val inte bara leder vidare till nästa sida i boken, utan till en ny situation, då behövs det kod. Det behövs kod för att hålla reda på vilken situation läsaren befinner sig i, vilka val som finns och vilka situationer som valen leder till.</p>
<p>En stor del av uppgiften att översätta äventyret till kod landar naturligt i att skapa en struktur för äventyret och i förlängningen en struktur för koden. Detta är en viktig del av programmering, att strukturera din data för att koden ska kunna hantera den.</p>
<h2 id="kom-ig%C3%A5ng" tabindex="-1">Kom igång</h2>
<p>Ett första steg i att koda ett äventyr av det här slaget brukar ganska ofta se ut som följer.</p>
<pre class="language-js"><code class="language-js">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Vad vill du göra?"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"1. Gå till dörren"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"2. Gå till fönstret"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Vad väljer du? "</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Äventyret skrivs ut med ett antal print statements och sedan får spelaren göra ett val med hjälp av <code>prompt</code>. Detta är en naturlig start och en bra början.<br>
Nästa steg är en if-sats för att hantera spelarens val. Denna if-sats har en tendens att växa och växa och sedan leder den till nästlade if-satser.</p>
<p>Detta är ett exempel där kodaren börjar med att koda utan att tänka på strukturen. Det är inget konstigt och ett naturligt steg i att lära sig lösa problem med kod.</p>
<p>Det är även mycket svårt för äventyret att växa utan att det blir mycket repetition i koden.</p>
<h2 id="struktur" tabindex="-1">Struktur</h2>
<p>Om en istället börjar med att tänka på textens (data/spelet) struktur så kan en komma fram till att det finns ett antal saker som behöver hanteras.</p>
<ul>
<li>Situationer</li>
<li>Val</li>
<li>Spelarens val</li>
<li>Spelarens position</li>
</ul>
<p>Men för att kunna översätta detta i kod så krävs det kunskap och förståelse om flera koncept.</p>
<p>Äventyret i sig, berättelsen är en händelse som upprepas om och om igen (tänk sidor i en bok). Spelaren får en text presenterad för sig, sedan utför spelaren ett val som leder till en ny situation. Detta är en loop som upprepas tills äventyret är över.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">while</span> <span class="token punctuation">(</span>spelet ska fortsätta<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// presentera situation</span>
    <span class="token comment">// presentera val</span>
    <span class="token comment">// spelaren gör ett val</span>
    <span class="token comment">// spelaren hamnar i en ny situation</span>
<span class="token punctuation">}</span></code></pre>
<p>Om spelet är linjärt som en bok så kan vi till exempel spara innehållet i en array, där varje position innehåller en sida i boken.</p>
<p>Du kan provköra koden genom att klistra in den i din webbläsares konsol.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> book <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">,</span>
  <span class="token string">"Du går till dörren."</span><span class="token punctuation">,</span>
  <span class="token string">"Du går till fönstret."</span>
<span class="token punctuation">]</span>

book<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>page<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<h2 id="situationer-och-val" tabindex="-1">Situationer och val</h2>
<p>Textäventyret är inte ett linjärt äventyr och spelaren presenteras löpande val och behöver fatta beslut. Den delen behöver koden hantera och med en genomtänkt struktur så kan en undvika att hamna i en stor if-sats.</p>
<p>En situation kan beskrivas som en text och en lista med val. Varje val består av en text och en referens till en annan situation. Detta kan översättas till kod med hjälp av objekt.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> book <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå till dörren"</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå till fönstret"</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">]</span></code></pre>
<p>Koden ovan ger möjligheten att beskriva spelarens val, de sparas i en parameter som är en array i objektet. Varje val är ett objekt som innehåller en text som beskriver valet. Men i exemplet ovan saknas något, nämligen möjligheten att referera till en ny situation. För att hänvisa till Soloäventyren från min barndom igen så hänvisar varje val till en ny sida i boken.</p>
<p>Sidreferensen översättas till kod med en parameter som refererar till en ny situation, ett mål och ett sidnummer. Parametern <code>target</code> pekar på ett objekt i listan som identifieras med hjälp av ett id.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> book <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Du vaknar upp i ett rum. Du ser en dörr och ett fönster."</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span>
      <span class="token punctuation">{</span>
        <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Gå till dörren"</span><span class="token punctuation">,</span>
        <span class="token literal-property property">target</span><span class="token operator">:</span> <span class="token number">1</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span>
    <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token literal-property property">description</span><span class="token operator">:</span> <span class="token string">"Du går till dörren."</span><span class="token punctuation">,</span>
    <span class="token literal-property property">choices</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">]</span></code></pre>
<h2 id="spelarens-val" tabindex="-1">Spelarens val</h2>
<p>När spelaren gör ett val så behöver koden veta vilken situation som spelaren befinner sig i. Detta kan lösas med en variabel som håller reda på spelarens position i äventyret. I enlighet med att äventyrets lista kallas book så deklareras variabeln som <code>page</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> page <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span></code></pre>
<h3 id="index-i-arrayer" tabindex="-1">Index i arrayer</h3>
<p>Ett sätt att lösa äventyrets sidor på och hålla reda på spelarens position är att använda <code>page</code> variabeln och leta reda på “rätt” sida med hjälp av listans index.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> page <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>book<span class="token punctuation">[</span>page<span class="token punctuation">]</span><span class="token punctuation">.</span>description<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Det är en fungerande lösning, men likt den nästlade if-satsen så har den en tendens att växa och växa. Det är inte en lösning som är lätt att utöka och underhålla. Vad händer när en vill lägga till en ny situation, när val ändras och när sidor tas bort?</p>
<p>Av den anledningen så är det bättre att använda en variabel som refererar till ett objekt i listan. Ett objekt som identifieras med hjälp av ett id. Datastrukturen som skapas för äventyret är på så sätt inte lika känslig för förändringar.</p>
<h2 id="anv%C3%A4nda-objekt-id-f%C3%B6r-spelarens-val" tabindex="-1">Använda objekt id för spelarens val</h2>
<p>För att använda objektens id för att hålla reda på spelarens position så behöver koden först hitta rätt objekt i listan. Detta kan göras med hjälp av en funktion som tar emot ett id och returnerar ett objekt.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">findPage</span><span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> book<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> page<span class="token punctuation">.</span>id <span class="token operator">===</span> <span class="token function">parseInt</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Funktionen använder sig av array-metoden <code>find</code> för att hitta rätt objekt i listan. <code>find</code> tar emot en funktion som parameter och denna funktion körs för varje objekt i listan. Om funktionen returnerar <code>true</code> så returneras objektet som <code>find</code> hittade. I funktionen som skickas till <code>find</code> så jämförs objektets id med id som skickades in som parameter. Om id matchar så returneras objektet.</p>
<p>Viktigt här är att vi måste konvertera <code>id</code> till ett heltal med <code>parseInt</code> för att jämföra med objektets id, detta eftersom prompt returnerar en sträng.</p>
<p>Med den koden så kan spelarens position i äventyret uppdateras med hjälp av objektets id.</p>
<h2 id="anv%C3%A4nda-strukturen-f%C3%B6r-att-presentera-%C3%A4ventyret" tabindex="-1">Använda strukturen för att presentera äventyret</h2>
<p>Med en tydlig struktur på plats blir det nu mycket enklare att presentera äventyret för spelaren. Detta kan göras med hjälp av en funktion som tar emot ett objekt och presenterar objektets beskrivning och val.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">displayPage</span><span class="token punctuation">(</span><span class="token parameter">page</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>page<span class="token punctuation">.</span>description<span class="token punctuation">)</span><span class="token punctuation">;</span>
  page<span class="token punctuation">.</span>choices<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">choice</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>choice<span class="token punctuation">.</span>description<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>Funktionen presenterar först objektets beskrivning och sedan presenteras varje val. Detta görs med hjälp av en <code>forEach</code>-loop som loopar igenom objektets <code>choices</code>-lista. Varje val presenteras med hjälp av <code>console.log</code>. Här kan en istället använda <code>prompt</code> för att låta spelaren göra ett val.</p>
<h2 id="presentera-%C3%A4ventyret-f%C3%B6r-spelaren" tabindex="-1">Presentera äventyret för spelaren</h2>
<p>Med funktionerna på plats så kan äventyret presenteras för spelaren. Detta görs med hjälp av en loop som upprepas tills äventyret är över.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> page <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

<span class="token keyword">while</span> <span class="token punctuation">(</span>page <span class="token operator">!==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> currentPage <span class="token operator">=</span> <span class="token function">findPage</span><span class="token punctuation">(</span>page<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">displayPage</span><span class="token punctuation">(</span>currentPage<span class="token punctuation">)</span><span class="token punctuation">;</span>
  page <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Vad väljer du? "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>I loopen så hämtas objektet som spelaren befinner sig i med hjälp av <code>findPage</code>-funktionen. Objektet presenteras sedan för spelaren med hjälp av <code>presentPage</code>-funktionen. Till sist så uppdateras spelarens position med hjälp av <code>prompt</code>.</p>
<p>Problemet här är att vi inte ännu använder valets targetId, utan att vi istället använder prompt för att låta spelaren göra ett val. Detta är en del som behöver implementeras för att äventyret ska fungera.</p>
<h2 id="implementera-spelarens-val" tabindex="-1">Implementera spelarens val</h2>
<p>För att implementera spelarens val så behöver vi använda valets targetId för att uppdatera spelarens position. Detta kan göras med hjälp av en funktion som tar emot ett val och uppdaterar spelarens position.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">makeChoice</span><span class="token punctuation">(</span><span class="token parameter">choice</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> choice<span class="token punctuation">.</span>target<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Funktionen tar emot ett val och returnerar valens targetId. Funktionen används sedan för att uppdatera spelarens position.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> page <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

<span class="token keyword">while</span> <span class="token punctuation">(</span>page <span class="token operator">!==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> currentPage <span class="token operator">=</span> <span class="token function">findPage</span><span class="token punctuation">(</span>page<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">displayPage</span><span class="token punctuation">(</span>currentPage<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">let</span> choice <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span><span class="token string">"Vad väljer du? "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  page <span class="token operator">=</span> <span class="token function">makeChoice</span><span class="token punctuation">(</span>currentPage<span class="token punctuation">.</span>choices<span class="token punctuation">[</span>choice<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Med den koden så kan spelaren göra ett val och hamna i en ny situation. Detta upprepas tills äventyret är över. Det är dock en ganska bräcklig lösning, vad händer om spelaren skriver in ett felaktigt val? Vad händer om spelaren skriver in ett val som inte finns?</p>
<h2 id="sammanfattning" tabindex="-1">Sammanfattning</h2>
<p>Pust, det är en sak att tänka sig en artikel som detta, en annan att skriva den. Texten kräver en del två och det ska ordnas, för att presentera ett äventyr med <code>console.log()</code> och <code>prompt()</code> är inte så kul.</p>
<p>Jag har uppdaterat koden något eftersom exemplet var ofullständigt.</p>
<p>Vill du testa koden så kan du klistra in den i din webbläsares konsol. Eller så hittar du koden på <a href="https://gist.github.com/jensadev/f09fd3d980929a512d8981a480883885" target="_blank" rel="noopener">github</a>. Prova gärna att utöka book objektet med fler sidor och val, då ser du en del av styrkan i att använda objekt för att strukturera data.</p>
<p>Presentationen för spelaren kan göras mycket bättre med hjälp av en webbsida och DOM-manipulation, och det ska vi titta på i <a href="/sv/posts/textaventyr-med-javascript-en-fortsattning">nästa del</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Att repetera för utveckling och lärande</title>
        <link href="https://jensa.dev/sv/posts/att-repetera-for-utveckling-och-larande/"/>
        <updated>Thu, 24 Aug 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/att-repetera-for-utveckling-och-larande/</id>
        <content type="html"><![CDATA[<p>Att repetera för att utvecklas och lära sig är inget nytt koncept, men det är ofta något som vi inte alltid prioriterar tillräckligt. Jag skriver detta för att påminna mig själv och för att dela mina tankar inför det kommande läsåret.</p>
<p>Det är också så att för att lära sig så behöver en använda. 🤯</p>
<h2 id="repetition" tabindex="-1">Repetition</h2>
<p>Min tanke är att inleda webbkurserna, både i trean och på te4, med repetition av grundläggande programmeringskoncept med javascript. Det blir en bra upprepning och jag är övertygad om att jag inte är ensam om att ha tagit en paus från kodning under sommaren.</p>
<h2 id="bygga-med-vite" tabindex="-1">Bygga med vite</h2>
<p>Jag har tidigare använt <a href="https://vitejs.dev/" target="_blank" rel="noopener"><abbr title="Vite är ett modernt ESM baserat byggverktyg som används främst för att utveckla webbapplikationer.">Vite</abbr></a> för olika ändamål, och min avsikt är att fortsätta med det. Att faktiskt använda det mer så att jag känner mig bekvämare med att använda det. Nu blir det lite att rycka av plåstret och köra, det ordnar sig. Därefter kommer frågor om bästa praxis och optimal användning, men jag är inte där än.</p>
<h2 id="github-actions" tabindex="-1">GitHub actions</h2>
<p>Eftersom <abbr title="Vite är ett modernt ESM baserat byggverktyg som används främst för att utveckla webbapplikationer.">Vite</abbr> är ett byggverktyg så är det ju bra att ha något som bygger det. Lokalt är enkelt med <code>npm run dev</code> men det är kanske inte alltid så intuitivt för eleverna att köra <code>npm run build</code> och sen få upp en <code>dist</code> mapp som ska publiceras. Så jag tänker att det är bra att ha något som bygger det automatiskt.</p>
<p>Detta leder mig såklart in på det faktum att jag är för dålig på <a href="https://github.com/features/actions" target="_blank" rel="noopener">GitHub Actions</a>, men detta är en utmärkt anledning att lära sig mer om det. Så det blir en bra övning för mig också.<br>
Sen som av en händelse så lyfter det en viktig poäng i att förstå GitHub, branches och att jobba med pull requests, så jag hoppas att det blir en pedagogiskt bra övning.</p>
<h2 id="slutligen" tabindex="-1">Slutligen</h2>
<p>Övningen som den här posten handlar om finns att betrakta på github, <a href="https://github.com/jensadev/wu2-js" target="_blank" rel="noopener">jensadev/wu2-js</a>, återstår att se hur det går.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Sommarlov 2023</title>
        <link href="https://jensa.dev/sv/posts/sommarlov-2023/"/>
        <updated>Tue, 20 Jun 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/sommarlov-2023/</id>
        <content type="html"><![CDATA[<p>Ett nytt skolår lider mot sitt slut. Det var nu ett tag sedan jag skrev här och anledningarna är såklart många. Det har varit en hel del personligt nu i slutet av terminen som påverkat mycket jag har gjort. Trots det så har det gått rätt så skapligt, vi nådde typ de uppsatta målen i årets kurser även om jag hade önskat att jag fått mina bedömningsdelar gjorda tidigare.</p>
<p>Jag har nu bytt namn på min GitHub-profil, så jag misstänker att jag kommer få leva med sneda länkar ett bra tag framöver. Nu är det <a href="https://github.com/jensadev" target="_blank" rel="noopener">jensadev</a>.</p>
<p>Ett kort <a href="https://gist.github.com/jensadev/c377e37ceb4138c4c29c6ab5f5f64c2f" target="_blank" rel="noopener">PM</a> över året.</p>
<h2 id="bra-saker" tabindex="-1">Bra saker</h2>
<ul>
<li>ULF projekt med andra lärare från hela landet, bra diskussioner och givande utbyte med kollegor kring webb och programmering.</li>
<li>Förstelärare-uppdrag med fokus på GitHub. Jag har fått med mig ett bättre tänk kring att lära ut hur en använder GitHub.
<ul>
<li>Material, <a href="https://git.jensa.dev/" target="_blank" rel="noopener">Git och GitHub</a></li>
<li>Bra workshop erfarenhet.</li>
</ul>
</li>
<li>Kursinnehåll, jag är på det stora hela nöjd och det kan bara bli bättre.</li>
</ul>
<h2 id="mindre-bra-saker" tabindex="-1">Mindre bra saker</h2>
<ul>
<li>Flera uppdrag, att leda och organisera ett projekt tar tid.</li>
<li>Bedömning, gör det i tid.</li>
<li>Kursinnehåll, vissa moment tar för mycket tid och räntar (kunskap) inte på önskat sätt.</li>
</ul>
]]></content>
    </entry>
    
    
    <entry>
        <title>Navbars</title>
        <link href="https://jensa.dev/sv/posts/navbars/"/>
        <updated>Mon, 29 May 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/navbars/</id>
        <content type="html"><![CDATA[<h2 id="b%C3%B6rja-h%C3%A4r" tabindex="-1">Börja här</h2>
<p>Instruktioner för den här sidans exempel visas på Codepen, det finns även förklarande text där.</p>
<p>Alla exempel som visas är responsiva, vilket innebär att de anpassar sig efter skärmstorleken på enheten.</p>
<p>I alla exempel används kombinationer av klasser för att styra navbarens beteende. Det innebär att många element har flera klasser, och de separeras med mellanslag.</p>
<div class="feature">
<p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="bGmZypm" data-user="jensadev" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jensadev/pen/bGmZypm">
  Navbars</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<h2 id="hamburgermeny" tabindex="-1">Hamburgermeny</h2>
<p>En hamburgermeny är en vanlig navigeringsmeny som används på webbsidor och appar för att visa en samling av länkar eller navigeringsalternativ på ett kompakt sätt.</p>
<h3 id="vad" tabindex="-1">Vad</h3>
<p>En hamburgermeny är en typ av navigeringsmeny som visas som tre horisontella linjer, vilket liknar utseendet på en hamburgare. När användaren klickar på hamburgerikonen visas eller döljs navigeringsmenyn.</p>
<h3 id="varf%C3%B6r" tabindex="-1">Varför</h3>
<p>Hamburgermenyn är användbar när det finns begränsat utrymme på skärmen, särskilt på mobila enheter. Den kompakta designen gör det möjligt för användaren att enkelt få tillgång till navigeringsalternativen genom att klicka på hamburgerikonen. Detta minimerar också synligheten av navigeringsmenyn när den inte används och ger mer utrymme för annat innehåll på webbsidan.</p>
<p>Betyder det att hamburgermenyn enbart ska användas på små enheter? Inte nödvändigtvis, men designmönstret påverkar tillgängligheten och användbarheten så det bör kunna motiveras.</p>
<div class="feature">
<p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="bGmZPPg" data-user="jensadev" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jensadev/pen/bGmZPPg">
  Navbars - hamburger</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>]]></content>
    </entry>
    
    
    <entry>
        <title>Sidebar layout</title>
        <link href="https://jensa.dev/sv/posts/sidebar-layout/"/>
        <updated>Fri, 26 May 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/sidebar-layout/</id>
        <content type="html"><![CDATA[<p>Koden i det här exemplet grundar sig på lösningen som går att finna i <a href="https://every-layout.dev/layouts/sidebar/" target="_blank" rel="noopener">Every Layout</a>, läs gärna mer där.</p>
<p>Som du kan se i exemplet så är det ganska mycket innehåll i sidebar delen, men det kan likväl vara enbart navigation.</p>
<div class="feature">
<p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="YzJggJo" data-user="jensadev" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jensadev/pen/YzJggJo">
  Sidebar layout</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<h2 id="ut%C3%B6ka" tabindex="-1">Utöka</h2>
<p>Med hjälp av css så är det tämligen enkelt att byta placering på sidebaren, från vänster till höger. Detta görs genom att byta ordningen på elementen med flex-direction.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">.with-sidebar</span> <span class="token punctuation">{</span>
  <span class="token property">flex-direction</span><span class="token punctuation">:</span> row-reverse<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Testa även att kombinera detta exempel med layout och hjälpklasserna från tidigare exempel. Kombinera centrering med sidebar layouten och navbar till exempel.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Content Security Policy</title>
        <link href="https://jensa.dev/sv/posts/content-security-policy/"/>
        <updated>Tue, 07 Feb 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/content-security-policy/</id>
        <content type="html"><![CDATA[<p><abbr title="Content Security Policy">CSP</abbr> är en HTTP response header som säkerställer att webbsidor inte kan ladda in innehåll från andra källor än de som är tillåtna. Detta är ett sätt att förhindra attacker som <abbr title="Cross Site Scripting">XSS</abbr> och <abbr title="Cross Site Request Forgery">CSRF</abbr>. Mer att läsa om det finns här på <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy" target="_blank" rel="noopener">Content-Security-Policy - HTTP | <abbr title="Mozilla Developer Network">MDN</abbr></a>.</p>
<p>Jag har tidigare tänkt på att fixa detta för den här webbplatsen, men inte riktigt kommit mig för detta. Men av en händelse så kollade jag <a href="https://observatory.mozilla.org/" target="_blank" rel="noopener">Mozilla Observatory</a>, en tjänst för att testa webbplatsens säkerhet. Resultatet för den här sidan var inte jättebra och en stor del av det beroende på att jag inte hade någon <abbr title="Content Security Policy">CSP</abbr>.</p>
<h2 id="s%C3%A4kra-webbplatsen" tabindex="-1">Säkra webbplatsen</h2>
<p>Eftersom den här sidan hostas på <a href="https://www.netlify.com" target="_blank" rel="noopener">Netlify</a> och byggs med <a href="https://11ty.dev" target="_blank" rel="noopener">11ty</a> så började jag att leta lite utifrån det. På Netlify så kan en <abbr title="Content Security Policy">CSP</abbr> anges i antingen <code>netlify.toml</code> eller i <code>_headers</code> (finns säkert <a href="https://docs.netlify.com/routing/headers/" target="_blank" rel="noopener">fler sätt</a>).</p>
<p>Jag hittade ett <a href="https://github.com/nhoizey/nicolas-hoizey.photo/blob/main/src/_headers.njk" target="_blank" rel="noopener">_headers exempel</a> för att bygga en <code>_headers</code> fil med <code>.njk</code> som verkade ganska rimlig, men problemet var att det inte löste att jag har stilarna inline i min HTML på sidan. Det går att lösa (inline stilar) genom att köra <code>unsafe-inline</code> för stilarna i <abbr title="Content Security Policy">CSP</abbr>, men konsensus verkar vara att då är det bättre att inte ha någon <abbr title="Content Security Policy">CSP</abbr> alls.</p>
<p>Jag tittade först på att använda en <code>nonce</code> men om en sådan ska genereras vid varje HTTP request så vet jag inte riktigt hur det skulle lösas. Sedan joxade jag lite med att sha256 hasha style strängen (som det är) i byggprocessen men jag tänkte att det borde finnas en enklare lösning.</p>
<h2 id="netlify-plugins" tabindex="-1">Netlify plugins</h2>
<p>Som oftast finns det en enklare lösning skapad av en smart person. Jag hittade ett plugin, <a href="https://github.com/MarcelloTheArcane/netlify-plugin-csp-generator" target="_blank" rel="noopener">Netlify plugin csp generator</a>, för att automatisera skapandet av en <abbr title="Content Security Policy">CSP</abbr> och hasha inline styles. Pluginet konfigureras i <code>netlify.toml</code> och genererar headers när projektet byggs.</p>
<p>Efter lite testande och fix så verkade det mesta funka, men sidan ger errors på inline styles, så något ställer till det. Så det finns lite kvar att göra.</p>
<h2 id="resultat" tabindex="-1">Resultat</h2>
<p>En bra mycket bättre score på <a href="https://observatory.mozilla.org/analyze/jensa.dev" target="_blank" rel="noopener">Observatory</a> och med detta en säkrare webbplats för dig som besöker den.</p>
<p>För min egen del så lite nya och utökade lärdomar om webbplatsers säkerhet.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Design remix</title>
        <link href="https://jensa.dev/sv/posts/design-remix/"/>
        <updated>Thu, 02 Feb 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/design-remix/</id>
        <content type="html"><![CDATA[<p>Jag har alldeles nyligen arbetat med att uppdatera min mors webbsida <a href="https://www.skareus.se" target="_blank" rel="noopener">skareus.se</a>. Jag ville få bort en del konstiga val jag tyckte var bra när jag skapade sidan runt 2016 (tror jag). Men framförallt så saknades möjligheten för henne att uppdatera sidan själv.</p>
<p>Jag letade bland <a href="https://www.11ty.dev/docs/starter/" target="_blank" rel="noopener">Starter projects</a> och hittade <a href="https://eleventy-netlify-boilerplate.netlify.app/" target="_blank" rel="noopener">Eleventy Netlify Boilerplate</a>, vilket fungerade utmärkt. Så det som kvarstod då var att skriva nya templater och css.</p>
<h2 id="inspiration" tabindex="-1">Inspiration</h2>
<p>Nu hade jag chansen att skriva om allt från grunden och använda nya lärdomar. Så jag passade på att titta på Andys talk – Be the browser’s mentor, not its micromanager för att inspireras och det gjorde det verkligen. Det är superintressant, smart och ger en fantastik grund att arbeta utifrån. Till presentationen så har han skapat en en demosida för att visa det han pratar om, <a href="https://buildexcellentwebsit.es/" target="_blank" rel="noopener">buildexcellentwebsit.es</a>.</p>
<div class="feature youtube-embed">
    <iframe 
        src="https://www.youtube-nocookie.com/embed/5uhIiI9Ld5M"
        title="YouTube video player"
        frameborder="0"
        allowfullscreen>
    </iframe>
    </div>
<p>Utöver detta så finns det även en 11ty starter baserat på presentationen, <a href="https://eleventy-excellent.netlify.app/" target="_blank" rel="noopener">eleventy-excellent</a>, skapad av <a href="https://www.lene.dev/" target="_blank" rel="noopener">Lene Saile</a>.</p>
<h2 id="css-och-att-skriva-mindre-och-b%C3%A4ttre-css" tabindex="-1">Css och att skriva mindre och bättre css</h2>
<p>Det händer att GitHub copilot läser mina tankar…</p>
<blockquote>
<p>Jag har alltid haft en känsla av att jag skriver för mycket css.</p>
</blockquote>
<p>Så full av inspiration började jag med målet att skriva mindre css när jag designade om <a href="https://www.skareus.se" target="_blank" rel="noopener">skareus.se</a> och det gick rätt så bra tycker jag. Det var roligt att göra och såklart började det då klia i fingrar att göra om den här sidan också.</p>
<h2 id="ny-design" tabindex="-1">Ny design</h2>
<p>När jag designade den här sidan ( och samtidigt joxade med <a href="/projekt/tod">tod</a> ) så läste jag en del om BEM, jag ville ha en systematik i min css. Jag använde mycket <a href="https://getbootstrap.com/" target="_blank" rel="noopener">Bootstrap</a> men för att lära mig mer så ville jag sluta med det. När jag sedan designade om den här sidan för nästan ett år sedan så levde så mycket css kvar från den gamla sidan. Det var inte bra.</p>
<h3 id="ett-blankt-blad" tabindex="-1">Ett blankt blad</h3>
<p>Jag började med att ta bort all CSS för sidan och ta bort alla klasser från html koden. Det var utgångspunkten. Jag gjorde även en insats med att förenkla html koden och ta bort en massa onödiga element (samt ta bort lite nunjucks-macro-besvärlighet).</p>
<p>Efter det så kunde arbetet med att applicera den metodik som Andy föreslår börja.</p>
<ul>
<li>Fluid type &amp; Space, <a href="https://utopia.fyi/" target="_blank" rel="noopener">Utopia</a></li>
<li>Flexible Layouts, en del eget men också från <a href="https://every-layout.dev/" target="_blank" rel="noopener">Every Layout</a></li>
<li>Progressive Enhancement</li>
</ul>
<p>Jag har inte följt allt fullt ut, men en hel del och det gör underverk tycker jag. Det jag känner och vill göra att eliminera så många specifika klasser som möjligt. Det kan vara så att jag går för långt, men det känns också som att den tidigarae designen var helt uppbyggd på klasser och undantag och det vill jag undvika.</p>
<h2 id="resultatet" tabindex="-1">Resultatet</h2>
<p>Ser du här och det är väl inte helt färdigt. Det är monotomt i färgvalet för det är där jag brukar landa, men jag ska fortsätta jobba på det. Det finns även en del som jag vill gå igenom igen och se om det går att göra bättre.</p>
<p>Jag tror att delen med koddemos kommer bli länkar till <a href="https://codepen.io/" target="_blank" rel="noopener">Codepen</a> istället för att ha koden direkt i sidan. Det är enklare att uppdatera och det blir lättare att dela. Sen är jag lur på att flytta resurserna till Git-Repos för att samla/versionshantera dem.</p>
<p>Så i vanlig ordning är cirkeln sluten, jag är tillbaka i det jag tänkte göra om. Men jag har lärt mig en del i processen 😊</p>
<p>Netlifys lighthouse plugin levererade även goda nyheter med uppdateringen:</p>
<p><picture><source type="image/webp" srcset="/img/Dtj5P-dBAt-300.webp 300w, /img/Dtj5P-dBAt-600.webp 600w, /img/Dtj5P-dBAt-900.webp 900w" sizes="100vw"><img alt="Lighthouse score" loading="lazy" decoding="async" src="/img/Dtj5P-dBAt-300.jpeg" width="900" height="773" srcset="/img/Dtj5P-dBAt-300.jpeg 300w, /img/Dtj5P-dBAt-600.jpeg 600w, /img/Dtj5P-dBAt-900.jpeg 900w" sizes="100vw"></picture></p>
<p>Det kan nog ha och göra med att jag rensat en hel del, men även bytt font från Typekit hostad till lokalt hostad <a href="https://github.com/weiweihuanghuang/Work-Sans" target="_blank" rel="noopener">Work Sans</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>2023, uppdateringar</title>
        <link href="https://jensa.dev/sv/posts/2023-uppdateringar/"/>
        <updated>Tue, 24 Jan 2023 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/2023-uppdateringar/</id>
        <content type="html"><![CDATA[<h2 id="janteckningar" tabindex="-1">JAnteckningar</h2>
<p>Under hösten har det skett ett antal förbättringar (tror jag) på sidan. Jag har arbetat lite med att få till <a href="https://developer.chrome.com/docs/lighthouse/overview/" target="_blank" rel="noopener">Lighthouse</a> poängen och det har blivit bättre. Det finns fortfarande saker att ordna med, PWA och en ständigt laggande font från typekit. 😠</p>
<p>Men såhär ser det ut för tillfället genom Netlifys Lighthouse-plugin. Bra enlight siffrorna, men 2.3s till interaktiv känns sådär.</p>
<p class="center"><picture><source type="image/webp" srcset="/img/zSOc3EtQHO-300.webp 300w, /img/zSOc3EtQHO-600.webp 600w" sizes="100vw"><img alt="Lighthouse poäng för jensa.dev" loading="lazy" decoding="async" src="/img/zSOc3EtQHO-300.jpeg" width="600" height="772" srcset="/img/zSOc3EtQHO-300.jpeg 300w, /img/zSOc3EtQHO-600.jpeg 600w" sizes="100vw"></picture></p>
<p>Det finns nu en samlingssida för <a href="/resurser">resurser</a>, men den behöver lite design-kärlek (troligast bara post-list komponenten).</p>
<p>Utöver det så har projektsidorna fått sig lite uppdateringar. Det finns nu bilder och lite annat och jag har ändrat data-formatet som det sparas i.</p>
<h2 id="github-copilot" tabindex="-1">GitHub CoPilot</h2>
<p>Copilot har blivit ett otroligt bekvämlighetsverktyg för att skriva kod, framförallt delar med någon form av upprepning där den snabb identifierar mönster och hjälper till med skrivandet.</p>
<p>Det är numera väldigt tydligt när jag inte har det påslaget, oklart om det är bra eller dåligt.</p>
<h2 id="projekt" tabindex="-1">Projekt</h2>
<h3 id="tod" tabindex="-1">TOD</h3>
<p>Tema, område, del rullar på och <a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">Webbutveckling</a> har fått mer innehåll och struktur. Jag har dessutom omarbetat en stor del av materialet så att det faktiskt är testbaserad inlärning. I nuläget finns det en del uppdateringar gjorda på <a href="https://tod.jensa.dev/" target="_blank" rel="noopener">grundsystemet</a> som behöver pushas till Webbutvecklings-sidan.</p>
<p>Jag har bland annat uppdaterat accordion komponenten så att den både är mer användbar och undviker gigantiska <a href="https://developers.google.com/publisher-tag/guides/minimize-layout-shift#:~:text=A%20layout%20shift%20occurs%20when,result%20of%20a%20user%20action." target="_blank" rel="noopener">layout-shifts</a>. Det är dock inget jag kan ta credit för utan det mesta kommer från <a href="https://inclusive-components.design" target="_blank" rel="noopener">Inclusive Components</a>, riktigt bra material.</p>
<h3 id="annat" tabindex="-1">Annat</h3>
<p>Jag har börjat joxa lite med <a href="https://reactjs.org/" target="_blank" rel="noopener">React</a> igen, får se vart det leder. Håller även på en del med <a href="https://phaser.io/phaser3" target="_blank" rel="noopener">Phaser</a>. Tanken är väl att hitta tillbaka till lite spelutveckling, men det är svårt att hitta tid för det. Målet är något med <a href="https://socket.io/" target="_blank" rel="noopener">socket.io</a> och multiplayer, men jag vill även hitta tiden till att skapa grafik antingen <a href="https://www.aseprite.org/" target="_blank" rel="noopener">pixel</a> eller <a href="https://www.blender.org/" target="_blank" rel="noopener">3D</a>. Det är inget som är nytt för mig, men det är områden som tar tid och jag är sjukt dammig på det för tillfället.</p>
<p>Har även testa <a href="https://eleventy-netlify-boilerplate.netlify.app/" target="_blank" rel="noopener">Eleventy Netlify Boilerplate</a> och möjligheten till att skapa admin verktyg genom <a href="https://www.netlifycms.org/" target="_blank" rel="noopener">Netlifycms</a> för att få en överblick / redigera innehåll till en statisk sida som denna är väldigt intressant.</p>
<h2 id="arbete" tabindex="-1">Arbete</h2>
<p>Jag är för närvarande involverad i ett ULF projekt med skolan där vi ska titta på hur olika arbetssätt påverkar elevers attityd till kod/webb, vilket är väldigt spännande.</p>
<p>I vår ska jag även köra workshop och försöka hjälpa fler att komma igång med att använda Git och GitHub i undervisningen, så det blir intressant att se hur det går.</p>
<h2 id="2023" tabindex="-1">2023</h2>
<p>To be continued…</p>
<p class="full"><picture><source type="image/webp" srcset="/img/K7RjPlv_wd-300.webp 300w, /img/K7RjPlv_wd-600.webp 600w, /img/K7RjPlv_wd-900.webp 900w" sizes="100vw"><img alt="Lysande storspov i rådhusparken" loading="lazy" decoding="async" src="/img/K7RjPlv_wd-300.jpeg" width="900" height="1200" srcset="/img/K7RjPlv_wd-300.jpeg 300w, /img/K7RjPlv_wd-600.jpeg 600w, /img/K7RjPlv_wd-900.jpeg 900w" sizes="100vw"></picture></p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Advent of code 2022</title>
        <link href="https://jensa.dev/sv/posts/advent-of-code-2022/"/>
        <updated>Fri, 02 Dec 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/advent-of-code-2022/</id>
        <content type="html"><![CDATA[<p>Igår drog <a href="https://adventofcode.com/" target="_blank" rel="noopener">Advent of Code</a> igång igen och jag kan verkligen rekommendera det. Utmana dig själv och försök lösa så många problem som möjligt. Du kommer att få parsa massor med data och hantera den på olika sätt, supernyttigt.</p>
<p>Förra året så lärde jag mig massor med bra saker tycker jag och hoppas på samma i år igen. Utmaningarna blev svårare och svårare och jag stötte på patrull nånstans mot slutet då det krävdes lite mer matte än vad jag kanske är van vid.</p>
<p>Hursomhelst så är målet i år att ta mig tiden till att förstå det samt att tvinga nån kollega (Magnus) att förklara grafteori och pathfindig för mig.</p>
<h2 id="k%C3%B6ra-med-javascript" tabindex="-1">Köra med JavaScript</h2>
<p>Jag kör med javascript och tänkte lite kort bara skriva om hur du kan köra med node för att lösa problemen. Om du är elev på skolan så vet jag att de flesta av er kör med Java, men det kan vara värt att prova något annat också.</p>
<ul>
<li>Se till att du har <a href="posts/webbserver-programmering/#nodejs">node installerat</a></li>
<li>Skapa en ny mapp för projektet <code>mkdir aoc2022</code>, och navigera till den med <code>cd aoc2022</code></li>
<li>Initiera ett nytt repo (så du kan spara hur det går med Git och jobba från olika datorer) <code>git init</code></li>
<li>Initiera ett nytt npm projekt <code>npm init -y</code></li>
<li>Kör igång vscode</li>
</ul>
<p>I filen <code>package.json</code> så under <code>scripts</code> så lägger du till följande:</p>
<pre class="language-json"><code class="language-json"><span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"node index.js"</span>
<span class="token punctuation">}</span></code></pre>
<p>Detta gör att du kan köra <code>npm start</code> för att köra din kod.</p>
<p>För att läsa in data från filer (både testinput och input) så använder du dig av <a href="https://nodejs.org/api/fs.html" target="_blank" rel="noopener">fs</a> och <a href="https://nodejs.org/api/path.html" target="_blank" rel="noopener">path</a> modulerna. Detta gör att du kan läsa in data från filer som ligger i samma mapp som din kod. Detta gör att du kan köra din kod mot testdata och sedan mot riktig data.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'fs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'path'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> data <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span>path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">'input.txt'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'utf-8'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Nu är du redo att jobba med Advent of Code. Lycka till och prata med oss lärare om du behöver komma åt skolans leaderboard.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Ny domän</title>
        <link href="https://jensa.dev/sv/posts/ny-doman/"/>
        <updated>Sun, 30 Oct 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/ny-doman/</id>
        <content type="html"><![CDATA[<p>En väldigt kort uppdatering om att jag är i processen att byta domän till <a href="https://jensa.dev" target="_blank" rel="noopener">jensa.dev</a>. Allt kommer vara samma, men istället för .xyz blir det .dev.</p>
<p>I nuläget fungerar redan det mesta men väntar på att DNS för <a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">webbutveckling</a> ska uppdateras.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Speedrun, centrerad layout</title>
        <link href="https://jensa.dev/sv/posts/speedrun-centrerad-layout/"/>
        <updated>Fri, 07 Oct 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/speedrun-centrerad-layout/</id>
        <content type="html"><![CDATA[<div class="feature">
  <p class="codepen" data-height="600" data-default-tab="html,result" data-slug-hash="BaqbYNP" data-user="jensadev" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
    <span>See the Pen <a href="https://codepen.io/jensadev/pen/BaqbYNP">
    Centrerad layout</a> by Jens Andreasson (<a href="https://codepen.io/jensadev">@jensadev</a>)
    on <a href="https://codepen.io">CodePen</a>.</span>
  </p>
  <script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
</div>
<h2 id="forts%C3%A4ttning" tabindex="-1">Fortsättning</h2>
<p>Exemplet ovan är bara ett exempel, en start. Kopiera in den i ditt dokument och bygg vidare. Gör den din och gör den unik, men försök hålla dig till layoutens grund. Kom ihåg <a href="https://lawsofux.com/jakobs-law/" target="_blank" rel="noopener">Jakobs law</a>.</p>
<blockquote>
<p>Users spend most of their time on other sites. This means that users prefer your site to work the same way as all the other sites they already know.</p>
</blockquote>
<h3 id="navbar" tabindex="-1">Navbar</h3>
<p>Styla texten, markera att det är navigation. Byt ut “logo” mot en faktisk logotyp.</p>
<p>Notera även att denna navbar får lite problem på små skärmar. Responsiviteten är inte riktigt där den bör vara. Ett sätt att arbeta med det är att skapa en mediaregel för mindre skärmar (exemplet nedan behöver dock lite mer).</p>
<pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">max-width</span><span class="token punctuation">:</span> 600px<span class="token punctuation">)</span></span> <span class="token punctuation">{</span>
  <span class="token selector">.navbar</span> <span class="token punctuation">{</span>
    <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="hero-%2F-header" tabindex="-1">Hero / header</h3>
<p>Header delen på sidan kan mycket väl ändras till en hero komponent. Texten kan places på bilden och en eventuell Call to action kan läggas till.</p>
<p>Att placera element på varandra har ofta gjorts med <code>position: relative</code> kombinerat med <code>position: absolute</code>. Det är ett sätt att göra det på som fungerar, men en mindre komplicerad lösning är att använda css grid och template-areas.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">.stack</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span>
    <span class="token property">grid-template-areas</span><span class="token punctuation">:</span> <span class="token string">"stack"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.stack > *</span> <span class="token punctuation">{</span>
    <span class="token property">grid-area</span><span class="token punctuation">:</span> stack<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="footer" tabindex="-1">Footer</h3>
<p>Prova gärna att skapa en footer till den här layouten, det är en bra övning. En sidfot är dessutom något som är en självklarhet på de flesta webbsidor.</p>
<p>Vad finns i en footer då? Surfa varsomhelst och titta (eller scrolla ner).</p>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>Nu fick jag chansen att prova på ett koddemo här på sidan och det krävde en del extra arbete. Templaten och Nunjucks macrot fungerar ok, men det blir lite problem med CSS-stilarna (stilen för <code>.demo-playground</code> försöker återställa stilarna så att inte flera ärvs från den här sidan, använd devtools för att kolla på det).</p>
<p>Med största sannolikhet hittar jag fler fel nästa gång… Tills dess.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Eleventy och sass</title>
        <link href="https://jensa.dev/sv/posts/eleventy-och-sass/"/>
        <updated>Fri, 07 Oct 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/eleventy-och-sass/</id>
        <content type="html"><![CDATA[<h2 id="innan-du-k%C3%B6r-ig%C3%A5ng" tabindex="-1">Innan du kör igång</h2>
<p>Se till att du kan skapa och få igång ett Eleventy-projekt. Behöver du hjälp med det så läs<a href="/posts/kom-igang-med-eleventy/">Kom igång med Eleventy</a>.</p>
<h2 id="sass" tabindex="-1">SASS</h2>
<p><a href="https://sass-lang.com/" target="_blank" rel="noopener">SASS</a> är ett CSS-preprocessor som gör det möjligt att använda funktioner och variabler i CSS. Det gör att du kan skriva mindre kod och att du kan återanvända kod. Det finns två olika versioner av SASS, SCSS och SASS. SCSS är en superset av CSS och är mer likt CSS än SASS. I det här exemplet kommer jag att använda SCSS.</p>
<p>Mycket av funktionerna i SASS finns nu tillgängliga direkt i CSS, men det finns fortfarande många funktioner som inte finns i CSS. Det är därför som många fortfarande använder SASS och därför är det fortfarande relevant att du lär dig hur du kan använda SASS.</p>
<h2 id="installera-sass" tabindex="-1">Installera SASS</h2>
<p>Du kan antingen välja att installera SASS globalt eller lokalt. För att installera npm paket global så används flaggan <code>-g</code>. Eftersom du kommer (om du läser webbutveckling 2) att hosta ditt projekt på <a href="https://www.netlify.com/" target="_blank" rel="noopener">Netlify</a> så behöver du installera SASS lokalt. Detta eftersom Netlify kommer att behöva se och installera SASS i byggprocessen eftersom det är en dependency till ditt projekt.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> sass</code></pre>
<h2 id="setup-f%C3%B6r-att-anv%C3%A4nda-sass" tabindex="-1">Setup för att använda SASS</h2>
<p>Skapa en mapp i ditt projekt som heter <code>src/sass</code>. I den mappen skapar du en fil som heter <code>style.scss</code>. Notera att filändelsen är <code>.scss</code> och inte <code>.css</code>. Detta eftersom vi vill använda SASS (med scss) och inte CSS.</p>
<p>Skapa en css-regel för att testa att SASS fungerar. I <code>style.scss</code> skriver du:</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">body </span><span class="token punctuation">{</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> red<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Kommandot för att bygga din css från din sass-fil är som följer och det går att köra direkt i bash. Vill du veta mer kolla <code>--help</code> flaggan.</p>
<pre class="language-bash"><code class="language-bash">npx sass src/sass/style.scss:dist/css/style.css</code></pre>
<p>Nästa steg är att skapa de script som kommer att kompilera din SASS till CSS. De scripten skriver du i <code>package.json</code>.</p>
<p>De script du behöver är ett för att uppdatera sass när du utvecklar och ett script för att bygga sass när du publicerar. För enkelhetens skull så kopiera följande till <code>package.json</code>. Innan du kan köra det så behöver du installera paketet <code>npm-run-all</code>.</p>
<pre class="language-json"><code class="language-json">    <span class="token property">"watch:sass"</span><span class="token operator">:</span> <span class="token string">"sass  --no-source-map --watch src/sass:dist/css"</span><span class="token punctuation">,</span>
    <span class="token property">"watch:eleventy"</span><span class="token operator">:</span> <span class="token string">"eleventy --serve"</span><span class="token punctuation">,</span>
    <span class="token property">"build:sass"</span><span class="token operator">:</span> <span class="token string">"sass  --no-source-map src/sass:dist/css"</span><span class="token punctuation">,</span>
    <span class="token property">"build:eleventy"</span><span class="token operator">:</span> <span class="token string">"eleventy"</span><span class="token punctuation">,</span>
    <span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"npm-run-all build:sass --parallel watch:*"</span><span class="token punctuation">,</span>
    <span class="token property">"build"</span><span class="token operator">:</span> <span class="token string">"npm-run-all build:sass build:eleventy"</span></code></pre>
<h2 id="eleventy-config" tabindex="-1">Eleventy config</h2>
<p>För att dra nytta av SASS tillsammans med Eleventy så behöver du konfigurera Eleventy. Det gör du i <code>eleventy.js</code>. För att de ändringar du gör i SASS filerna ska trigga en rebuild av Eleventy så behöver du konfigurera en watch target. Det gör du genom att lägga till följande i <code>eleventy.js</code>.</p>
<pre class="language-js"><code class="language-js">eleventyConfig<span class="token punctuation">.</span><span class="token function">addWatchTarget</span><span class="token punctuation">(</span><span class="token string">"./src/sass/"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Nu startar du Eleventy med <code>npm run start</code> och du bör se att din bakgrundsfärg är röd. Detta eftersom vi satt bakgrundsfärgen till röd i <code>style.scss</code>. Ändra färgen till något annat och se att det uppdateras i din webbläsare.</p>
<h2 id="css-reset-med-sass" tabindex="-1">CSS reset med SASS</h2>
<p>En bra sak att ha som de flesta sidor behöver är en <a href="https://meyerweb.com/eric/tools/css/reset/" target="_blank" rel="noopener">CSS reset</a>. Det är en CSS-fil som sätter alla element till samma värden. Det gör att du kan vara säker på att alla element har samma utseende oavsett vilken webbläsare du använder. Det finns många olika CSS resets men jag brukar oftast använda mig <a href="https://piccalil.li/blog/a-modern-css-reset/" target="_blank" rel="noopener">Andy Bells modern CSS reset</a> version eller <a href="https://github.com/5t3ph" target="_blank" rel="noopener">Stephanie Eckles</a> modifierade version.</p>
<p>Den reset som jag använder på den här sidan finns på GitHub, <a href="https://github.com/jensadev/jensa.dev/blob/main/src/sass/global/_reset.scss" target="_blank" rel="noopener">_reset.scss</a>. Du kan testa att använda den i din SASS-fil och se att den fungerar. Spara filen som <code>_reset.scss</code>, ett understreck i filnamnet indikerar att det är en partial och att den inte ska kompileras till CSS.</p>
<p>För att använda den så behöver du importera den i din <code>style.scss</code> fil. Det gör du genom att skriva följande:</p>
<pre class="language-scss"><code class="language-scss"><span class="token keyword">@use</span> <span class="token string">"reset"</span><span class="token punctuation">;</span></code></pre>
<h2 id="n%C3%A4sta-steg" tabindex="-1">Nästa steg</h2>
<p>Du har nu en grund för att kunna använda SASS med Eleventy, du kan börja med att skriva vanlig CSS i SCSS filen. Det fungerar bra så länge, men du kan nu allt eftersom lära dig mer om SASS och dess funktioner och inludera det i din CSS.</p>
<p>Ett tips är att kolla på <a href="https://sass-lang.com/documentation" target="_blank" rel="noopener">SASS dokumentationen</a> och <a href="https://sass-lang.com/guide" target="_blank" rel="noopener">SASS guiden</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Node version, obehagliga överraskningar</title>
        <link href="https://jensa.dev/sv/posts/node-version-obehagliga-overraskningar/"/>
        <updated>Thu, 06 Oct 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/node-version-obehagliga-overraskningar/</id>
        <content type="html"><![CDATA[<h2 id="problem" tabindex="-1">Problem</h2>
<p>Netlify kunde inte köra byggscriptet för <a href="/projekt/tema-omrade-del/">Tema, område, del</a>. Det felmeddelande som Netlify gav var kanske inte supertydligt heller.</p>
<pre class="language-bash"><code class="language-bash"><span class="token number">5</span>:53:08 PM: <span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> Eleventy CLI Fatal Error: <span class="token punctuation">(</span>more <span class="token keyword">in</span> DEBUG output<span class="token punctuation">)</span>
<span class="token number">5</span>:53:08 PM: <span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> <span class="token number">1</span>. Error <span class="token keyword">in</span> your Eleventy config <span class="token function">file</span> <span class="token string">'/opt/build/repo/.eleventy.js'</span><span class="token builtin class-name">.</span> <span class="token punctuation">(</span>via EleventyConfigError<span class="token punctuation">)</span>
<span class="token number">5</span>:53:08 PM: <span class="token punctuation">[</span>11ty<span class="token punctuation">]</span> <span class="token number">2</span>. Unexpected token <span class="token string">'.'</span> <span class="token punctuation">(</span>via SyntaxError<span class="token punctuation">)</span></code></pre>
<p>Som en stjärna ledde detta till att jag gjorde ett antal commits för att lösa problemet (som jag inte kunde reproducera lokalt), men inget fungerade. Det fungerade inte eftersom allt berodde på att min lokala Node version är 16+ och Netlify använde v12.18.0. Detta gjorde att Netlify failade och inte kunde bygga sidan.</p>
<h2 id="l%C3%B6sning" tabindex="-1">Lösning</h2>
<p>Uppdatera Node version som Netlify använder, men hur?</p>
<p>Det finns två sätt att göra det på, antingen via Netlify UI eller via Netlify.toml.</p>
<h3 id="via-netlify-ui" tabindex="-1">Via Netlify UI</h3>
<ol>
<li>Gå till din sida på Netlify</li>
<li>Klicka på “Site settings”</li>
<li>Klicka på “Build &amp; deploy”</li>
<li>Klicka på “Edit settings”</li>
<li>Klicka på “Environment”</li>
<li>Klicka på “New variable”</li>
<li>Skriv in “NODE_VERSION” i “Name”</li>
<li>Skriv in önskad Node version i “Value”</li>
<li>Klicka på “Save”</li>
</ol>
<h3 id="via-netlify.toml" tabindex="-1">Via Netlify.toml</h3>
<ol>
<li>Skapa en fil som heter <code>netlify.toml</code> i roten för ditt projekt</li>
<li>Skriv in följande</li>
</ol>
<pre class="language-toml"><code class="language-toml"><span class="token punctuation">[</span><span class="token table class-name">build</span><span class="token punctuation">]</span>
  <span class="token key property">publish</span> <span class="token punctuation">=</span> <span class="token string">"public"</span>
  <span class="token key property">command</span> <span class="token punctuation">=</span> <span class="token string">"npm run build"</span>
  <span class="token key property">environment</span> <span class="token punctuation">=</span> <span class="token punctuation">{</span> <span class="token key property">NODE_VERSION</span> <span class="token punctuation">=</span> <span class="token string">"18"</span> <span class="token punctuation">}</span></code></pre>
]]></content>
    </entry>
    
    
    <entry>
        <title>Eleventy, del två</title>
        <link href="https://jensa.dev/sv/posts/eleventy-del-tva/"/>
        <updated>Fri, 30 Sep 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/eleventy-del-tva/</id>
        <content type="html"><![CDATA[<h2 id="innan-du-k%C3%B6r-ig%C3%A5ng" tabindex="-1">Innan du kör igång</h2>
<p>Se till att du kan skapa och få igång ett Eleventy-projekt. Den första delen av artikeln handlar om det och den finns här, <a href="/posts/kom-igang-med-eleventy/">Kom igång med Eleventy</a>.</p>
<h2 id="collections" tabindex="-1">Collections</h2>
<p>Istället för ett innehåll skapat i datafiler så kan Eleventy skapa samlad data från innehållet på webbplatsen. Om du tillexempel skapar innehåll för en blogg så kan du använda collections för att skapa en lista med alla blogginlägg. För att testa detta så skapa en ny markdown fil i <code>src</code> och kalla den för <code>blog.njk</code>. Lägg till följande innehåll.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml">layout: base.njk
title: Blogg</span>
<span class="token punctuation">---</span></span>
Alla blogginlägg</code></pre>
<p>Notera att filen ovan är en Nunjucks fil istället för en markdown fil. Det gör att Eleventy inte kommer att läsa in innehållet i filen som markdown utan som Nunjucks. På det sättet så kan du använda Nunjucks syntax i filen tillsammans med frontmatter.</p>
<p>Nästa stycke kod använder <a href="https://www.11ty.dev/docs/collections/" target="_blank" rel="noopener">Eleventy collections</a> för att skapa en lista över alla blogposts. Det är väldigt användbart och kan användas för att skapa eller visa data.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
{% for post in collections.blog %}
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>{{ post.url }}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>{{ post.data.title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
    {{ post | log }}
{% endfor %}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span></code></pre>
<p>I templaten så används variabeln <code>collections</code> för att hämta data från innehållet, i det här fallet allt innehåll taggat med “blog”. Med hjälp av en for loop så skapas sedan en lista med blogginlägg.</p>
<p>Än så länge så har du bara skapat en sida för att visa en lista över alla sidor taggade med “blog”. De faktiska blogginläggen som ska visas ska du skapa i en egen mapp. Skapa mappen <code>src/blog</code>. I mappen kan du sedan använda en ytterligare Eleventy funktion, mapp-datafiler. Mapp-datafiler är json filer som innehåller data som appliceras som frontmatter på alla filer i mappen. Skapa en fil i <code>src/blog</code> och kalla den för <code>blog.json</code>. Lägg till följande innehåll.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"layout"</span><span class="token operator">:</span> <span class="token string">"base.njk"</span><span class="token punctuation">,</span>
    <span class="token property">"tags"</span><span class="token operator">:</span> <span class="token string">"blog"</span>
<span class="token punctuation">}</span></code></pre>
<p>Det filen <code>blog.json</code> kommer att göra är att sätta layouten till <code>base.njk</code> och taggen till <code>blog</code> på alla filer i mappen. Tags kan vara en enkel sträng eller en array av strängar. Nu kan du skapa markdown filer i mappen <code>src/blog</code> och de kommer att använda layouten och taggen som du har satt i <code>blog.json</code>.</p>
<p>Skapa en ny markdown fil i <code>src/blog</code> och kalla den för <code>first-post.md</code>. Lägg till följande innehåll.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml">title: First post</span>
<span class="token punctuation">---</span></span>
Detta är min första bloggpost.</code></pre>
<p>Uppdatera nu navigationen så att du kan surfa till din blog.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"Blogg"</span><span class="token punctuation">,</span>
    <span class="token property">"url"</span><span class="token operator">:</span> <span class="token string">"/blog/"</span>
<span class="token punctuation">}</span></code></pre>
<p>Nu kan du testa att skapa fler blogginlägg (det vill säga ytterligare markdown filer i mappen blog) och se att de dyker upp i listan. Om du är uppmärksam kanske du märkte att filnamnet blev <code>first-post</code>, engelska för första inlägg. Detta för att undvika svenska tecken i filnamnet. Det går såklart att lösa, men mer om det senare.</p>
<h2 id="bilder" tabindex="-1">Bilder</h2>
<p>Något som alltid dyker upp i webbkurserna är att inkludera bilder på webbplatsen. Det kan göras på ett antal olika sätt, dels som bilder i html, men även som bakgrunder med css.</p>
<p>Ett sätt att snabbt använda bilder i Eleventy är att kopiera dem på samma sätt som du <a href="/posts/kom-igang-med-eleventy/#css">tidigare gjort med css</a>. För att göra det så skapar du en mapp för bilderna i src, <code>src/images</code>. Kopiera sedan in de bilder du önskar använda i mappen.<br>
Slutligen behöver du säga åt Eleventy att faktiskt kopiera bilderna, det gör du med <code>addPassthroughCopy</code> i <code>eleventy.js</code>.</p>
<pre class="language-javascript"><code class="language-javascript">eleventyConfig<span class="token punctuation">.</span><span class="token function">addPassthroughCopy</span><span class="token punctuation">(</span><span class="token string">"src/images"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Nu kan du använda bilderna med markdown. För att göra det så lägger du till en bildtagg i markdown. Bildtaggen ser ut så här.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token url"><span class="token operator">!</span>[<span class="token content">alt text</span>](<span class="token url">/images/bildnamn.jpg</span>)</span></code></pre>
<h3 id="bildoptimering-med-eleventy-img" tabindex="-1">Bildoptimering med Eleventy-img</h3>
<p>I steget här ovan så var det främst en fråga om att kopiera bilden så att du kan använda den. Det är såklart ett fungerande sätt att göra det på, men det förutsätter att du sköter bildoptimering manuellt. Med bildoptimering menas att du anpassar bildens upplösning, storlek och format utifrån hur den ska användas på sidan. Att anpassa bilden efter användningen är viktigt och gör att din webbsida laddas snabbare och att användaren får en bättre upplevelse.</p>
<p>Eleventy kan sköta bildoptimeringen åt oss, med hjälp av ett plugin. <a href="https://www.npmjs.com/search?q=eleventy-plugin" target="_blank" rel="noopener">Plugins</a> är något det finns en uppsjö av i Eleventy och de kan användas för att utöka funktionaliteten. För att optimera bilderna på din webbplats kommer du att använda <a href="https://www.11ty.dev/docs/plugins/image/" target="_blank" rel="noopener">Eleventy-img</a>. Det är ett plugin som optimerar bilderna åt oss när vi bygger webbplatsen.</p>
<h4 id="installation" tabindex="-1">Installation</h4>
<p>För att installera pluginet så kör du följande kommando i terminalen.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> @11ty/eleventy-img</code></pre>
<p>För att använda ett plugin så behöver det registreras i <code>eleventy.js</code>. Det gör du genom att lägga till följande kod (i det här fallet för Eleventy-img).</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> Image <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"@11ty/eleventy-img"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<h4 id="anv%C3%A4ndning" tabindex="-1">Användning</h4>
<p>Det här exemplet är hämtat från <a href="https://www.11ty.dev/docs/plugins/image/" target="_blank" rel="noopener">Eleventy-img</a> dokumentationen. Det är en bild som ska visas på en sida med en bredd på 800px. Bilden ska vara i formatet jpg och ska vara av hög kvalitet. För att skapa bilden så skapar du en funktion i <code>eleventy.js</code> som ser ut så här.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">imageShortcode</span><span class="token punctuation">(</span><span class="token parameter">src<span class="token punctuation">,</span> alt<span class="token punctuation">,</span> sizes</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">let</span> metadata <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">Image</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">widths</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token number">800</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token literal-property property">formats</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"jpg"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token literal-property property">urlPath</span><span class="token operator">:</span> <span class="token string">"/images/"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">outputDir</span><span class="token operator">:</span> <span class="token string">"./dist/images/"</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">let</span> imageAttributes <span class="token operator">=</span> <span class="token punctuation">{</span>
    alt<span class="token punctuation">,</span>
    sizes<span class="token punctuation">,</span>
    <span class="token literal-property property">loading</span><span class="token operator">:</span> <span class="token string">"lazy"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">decoding</span><span class="token operator">:</span> <span class="token string">"async"</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> Image<span class="token punctuation">.</span><span class="token function">generateHTML</span><span class="token punctuation">(</span>metadata<span class="token punctuation">,</span> imageAttributes<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Funktionen tar in tre parametrar, <code>src</code>, <code>alt</code> och <code>sizes</code>. <code>src</code> är sökvägen till bilden, <code>alt</code> är en beskrivning av bilden och <code>sizes</code> är en sträng som beskriver hur stor bilden ska vara. I exemplet ovan så är bilden 800 pixlar bred.</p>
<p>För att använda funktionen så lägger du till följande kod i <code>eleventy.js</code>.</p>
<pre class="language-javascript"><code class="language-javascript">eleventyConfig<span class="token punctuation">.</span><span class="token function">addNunjucksAsyncShortcode</span><span class="token punctuation">(</span><span class="token string">"image"</span><span class="token punctuation">,</span> imageShortcode<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Nu kan du använda funktionen i markdown. För att göra det så lägger du till en bildtagg i markdown. Bildtaggen ser ut så här.</p>
<pre class="language-markdown"><code class="language-markdown">{% image "/images/bildnamn.jpg", "alt text", "800px" %}</code></pre>
<p>För att se hur funktionen fungerar så se till att Eleventy körs (kom ihåg att du kan behöva starta om ditt start script då du gjort ändringar i <code>.eleventy.js</code>), det gör du med <code>npm start</code>. När du har byggt webbplatsen så kan du öppna den i webbläsaren och se att bilden fungerar som den ska. Ta fram utvecklarverktygen i webbläsaren och kolla att bilden har en storlek på 800px, då kommer du även att se den html som pluginet genererat för bilden.</p>
<p>Detta var en kort introduktion till hur du kan använda Eleventy-img för att optimerar bilderna på din webbplats. Läs vidare i dokumentationen för att se hur du kan använda pluginet för att optimera bilderna ytterligare (Format, olika storlekar och så vidare).</p>
<h2 id="elventy-och-template%2C-att-skapa-sidor-och-%C3%A4rva-layout" tabindex="-1">Elventy och template, att skapa sidor och ärva layout</h2>
<p>TODO 🙂</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Kom igång med Eleventy</title>
        <link href="https://jensa.dev/sv/posts/kom-igang-med-eleventy/"/>
        <updated>Thu, 29 Sep 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/kom-igang-med-eleventy/</id>
        <content type="html"><![CDATA[<p>Det här inlägget riktar sig främst till dig som läser Webbutveckling 2 där vi använder <a href="https://11ty.dev" target="_blank" rel="noopener">Eleventy</a>. Jag har tidigare skrivit om att använda <a href="/posts/arbeta-med-eleventy-i-klassrummet/">eleventy i klassrummet</a>, men det är om Eleventy hur fungerar i undervisningssyfte.</p>
<h2 id="innan-du-k%C3%B6r-ig%C3%A5ng" tabindex="-1">Innan du kör igång</h2>
<p>För att följa denna introduktion så kräver det att du har installerat Node, NPM och WSL, du kan hitta hur i <a href="/posts/webbserver-programmering/">installationsposten för webbserverprogrammering</a>.</p>
<p>Det är även en fördel om du har lite koll på markdown och javascript.</p>
<p>När jag började använda Eleventy för egen del så kodade jag igenom den här <a href="https://egghead.io/courses/build-an-eleventy-11ty-site-from-scratch-bfd3" target="_blank" rel="noopener">videoserien</a>. Det är såklart frivilligt men kan vara ett alternativ för dig som föredrar video.</p>
<h2 id="vad-%C3%A4r-eleventy-d%C3%A5%3F" tabindex="-1">Vad är Eleventy då?</h2>
<p><picture><source type="image/webp" srcset="/img/dkCb7Zve2b-300.webp 300w" sizes="20vw"><img alt="11ty mascot" loading="lazy" decoding="async" src="/img/dkCb7Zve2b-300.jpeg" width="300" height="587"></picture></p>
<p>Eleventy är en static site builder, eleventy bygger statiska webbsidor. Eleventy är ett verktyg som ger dig mer kontroll, bättre arbetssätt och en förbättrad utvecklingsupplevelse (Developer experience, DX) med grundläggande webbtekniker som HTML, CSS och JavaScript. Det utan att förlita sig på stora bygg eller ramverk som påverkar användarens upplevelse (User experience, UX).</p>
<p>Eleventy är inte svaret på alla utvecklingsutmaningar, men det är ett verktyg och det är ditt jobb som utvecklare att veta när det passar att använda.</p>
<p>Eleventy underlättar arbetet med html med hjälp av template-språk. I den här guiden kommer du att använda <a href="https://www.markdownguide.org/" target="_blank" rel="noopener">Markdown</a> tillsammans <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks</a>.</p>
<p>Markdown är fantastiskt, lär dig det, använd det. Nunjucks är en smaksak, Eleventy stöder ett stort antal template-språk om du inte gillar Nunjucks. Ett tips för att göra arbetet med Nunjucks lite enklare är att säga åt VS code att hantera <code>njk</code> som <code>html</code>.</p>
<blockquote>
<p>Tips du kan skriva markdown i google docs.</p>
</blockquote>
<h2 id="hur%3F" tabindex="-1">Hur?</h2>
<p>Skapa en ny mapp för ditt projekt och initialisera ett nytt projekt med npm där. Kommandot <code>npm init -y</code> skapar <code>package.json</code>.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">mkdir</span> 11ty-intro
<span class="token builtin class-name">cd</span> 11ty-intro
<span class="token function">npm</span> init <span class="token parameter variable">-y</span></code></pre>
<p>Den skapade filen <code>package.json</code> ser ut så här.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"11ty-intro"</span><span class="token punctuation">,</span>
    <span class="token property">"version"</span><span class="token operator">:</span> <span class="token string">"1.0.0"</span><span class="token punctuation">,</span>
    <span class="token property">"description"</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span>
    <span class="token property">"main"</span><span class="token operator">:</span> <span class="token string">"index.js"</span><span class="token punctuation">,</span>
    <span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">"test"</span><span class="token operator">:</span> <span class="token string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">"keywords"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">"author"</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span>
    <span class="token property">"license"</span><span class="token operator">:</span> <span class="token string">"ISC"</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="installation" tabindex="-1">Installation</h3>
<p>För att installera Eleventy skriver du <code>npm install @11ty/eleventy</code>. Detta kommer att installera Eleventy och lägga till det som en dependency i <code>package.json</code>.</p>
<p>Noter att nu skapas en <code>package-lock.json</code> som håller koll på vilka versioner av paket som används. <code>package-lock.json</code> är inte en fil som du ska redigera manuellt utan den skapas automatiskt av NPM.</p>
<p>I filen <code>package.json</code> så kan du se att Eleventy har lagts till som en dependency.</p>
<pre class="language-json"><code class="language-json"><span class="token property">"dependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"@11ty/eleventy"</span><span class="token operator">:</span> <span class="token string">"^1.0.2"</span>
<span class="token punctuation">}</span></code></pre>
<p>Innan du kan starta upp eleventy så behöver du skapa ett startskript i <code>package.json</code>. Rediger filen och lägg till följande i <code>scripts</code>.</p>
<pre class="language-json"><code class="language-json"><span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">"start"</span><span class="token operator">:</span> <span class="token string">"eleventy --serve"</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="en-f%C3%B6rsta-fil" tabindex="-1">En första fil</h3>
<p>För att skapa en html-sida från en markdown fil behöver du inte göra mer än att skapa en markdown fil i projektets rot. Kalla filen för <code>index.md</code>.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token title important"><span class="token punctuation">#</span> Hello world</span>

Markdown till html med <span class="token url">[<span class="token content">11ty</span>](<span class="token url">https://11ty.dev</span>)</span>!</code></pre>
<p>Nu kan du testa att bygga sidan med Eleventy. Kör <code>npm start</code> i terminalen. Detta kommer att starta en lokal webbserver på <a href="http://localhost:8080/" target="_blank" rel="noopener">http://localhost:8080/</a>. Öppna sedan addressen i din webbläsare. Du kan nu redigera <code>index.md</code> och se hur sidan uppdateras i webbläsaren (det sker med ett verktyg som heter Browsersync).</p>
<p>Om du undersöker den html som Eleventy skapat så hittar du den i mappen <code>_site</code>. Öppna filen <code>index.html</code> med VS code. Som du ser så har Eleventy omvandlat markdown till html, men det saknas grundläggande taggar för att skapa ett <a href="https://validator.nu/" target="_blank" rel="noopener">validerande html-dokument</a>.</p>
<p>För att skapa ett komplett dokument så kommer behöver du konfigurera Eleventy att använda en template fil. Innan du kan göra det så behöver du skapa en mapp och konfigurationsfil. Kör följande kommandon från projektets rot.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">mkdir</span> src
<span class="token function">touch</span> .eleventy.js</code></pre>
<p>I filen <code>.eleventy.js</code> finns Eleventy konfigurationen. Öppna filen och redigera den. Koden här nedanför är en minimal konfiguration för att komma igång. Det är en start och du kan alltid använda den som en grund. Du kan läsa mer om konfigurationen <a href="https://www.11ty.dev/docs/config/" target="_blank" rel="noopener">här</a>.</p>
<pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">eleventyConfig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">dir</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token literal-property property">input</span><span class="token operator">:</span> <span class="token string">"src"</span><span class="token punctuation">,</span>
            <span class="token literal-property property">output</span><span class="token operator">:</span> <span class="token string">"dist"</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>Den här konfigurationen säger åt Eleventy att läsa innehållet från mappen <code>src</code> och att skriva ut det till mappen <code>dist</code>. Vi kommer att lägga våra markdown filer i <code>src</code> och Eleventy kommer att skapa html filer i <code>dist</code>.</p>
<p>Eftersom Eleventy nu utgår från <code>src</code> mappen så behöver du flytta innehållet dit. Flytta <code>index.md</code> till <code>src</code>. Kör sedan <code>npm start</code>. Sidan bör fortfarande byggas, med skillnaden att Eleventy sparar html filer i <code>dist</code> istället för <code>_site</code>.</p>
<h3 id="templates" tabindex="-1">Templates</h3>
<p>Templaterna till Eleventy sparar du i mappen <code>src/_includes</code>. Mappen <code>_includes</code> är förkonfigurerad för att innehålla Eleventy templater, så Eleventy tittar automatiskt där. Template språket som den här guiden använder är <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks</a>.</p>
<p>Skapa en ny fil i <code>src/_includes</code> och kalla den för <code>base.njk</code>. Den här filen kommer att innehålla grundläggande html-taggar för att skapa ett validerande html-dokument.</p>
<pre class="language-html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sv<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">http-equiv</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>X-UA-Compatible<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>IE=edge<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>{{ title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
    {{ content | safe }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<p>Som du ser så är det mer eller mindre ett html-dokument. Det som skiljer sig är att dokumentet använder variabler, <code>title</code> och <code>content</code>. Variablerna kommer att fyllas med data från markdown filerna. Variablerna är en del av hur Eleventy arbetar med templaterna. Notera att för variabeln <code>content</code> så används ett filter, <code>safe</code>. Detta är för att säkerställa att innehållet i variabeln inte filtreras bort. Det finns ett sort antal inbyggda <a href="https://mozilla.github.io/nunjucks/templating.html#builtin-filters" target="_blank" rel="noopener">filter i Nunjucks</a> och du kallar på dem med <code>|</code> följt av filternamnet.</p>
<p>Innan en templat kan används så måste Eleventy veta att den ska användas, det behöver anges i <code>index.md</code>. Valet av templat anges i markdown filen med frontmatter. Frontmatter är en del av markdown som används för att lägga till metadata om markdown filen. Frontmatter börjar och slutar med tre bindestreck. I exemplet nedan så anges att <code>base.njk</code> ska användas för att skapa html filen.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml">layout: base.njk
title: Hem</span>
<span class="token punctuation">---</span></span></code></pre>
<h3 id="css" tabindex="-1">CSS</h3>
<p>För att kunna använda CSS filer så behöver du konfigurera Eleventy att kopiera dem till <code>dist</code>. Filerna behöver kopieras av systemet då dist mappen är något som byggs när du kör Eleventy. Skapa mappen <code>src/css</code>. I mappen <code>css</code> skapar du sedan en css fil, <code>style.css</code>. För att Eleventy ska kopiera mappen behöver du lägga till följande kod i <code>.eleventy.js</code>.</p>
<pre class="language-js"><code class="language-js">eleventyConfig<span class="token punctuation">.</span><span class="token function">addPassthroughCopy</span><span class="token punctuation">(</span><span class="token string">"src/css"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Nu kan du redigera css filen du har skapat. Lägg till följande kod.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">body</span> <span class="token punctuation">{</span>
    <span class="token property">--container-width</span><span class="token punctuation">:</span> 80ch<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> <span class="token function">min</span><span class="token punctuation">(</span><span class="token function">var</span><span class="token punctuation">(</span>--container-width<span class="token punctuation">)</span><span class="token punctuation">,</span> 100vw - 1rem<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">margin-inline</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span>

    <span class="token property">font-family</span><span class="token punctuation">:</span> sans-serif<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Uppdatera sedan <code>base.njk</code> så att den använder CSS filen. Notera att sökvägen till filerna ska börja med <code>/</code> och aldrig heller innehålla <code>src</code> eller <code>dist</code>.</p>
<pre class="language-html"><code class="language-html">    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/css/style.css<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></code></pre>
<h2 id="hur-anv%C3%A4nder-jag-markdown%2C-nunjucks-och-eleventy%3F" tabindex="-1">Hur använder jag Markdown, Nunjucks och Eleventy?</h2>
<p>Eleventy kan skapa flera sidor från markdown filer. För varje markdown fil i <code>src</code> skapas html. Testa detta genom att skapa en till fil, kalla den för <code>om.md</code>. I filen kan du lägga till följande innehåll.</p>
<pre class="language-markdown"><code class="language-markdown"><span class="token front-matter-block"><span class="token punctuation">---</span>
<span class="token front-matter yaml language-yaml">layout: base.njk
title: Om</span>
<span class="token punctuation">---</span></span>
Om den här sidan.</code></pre>
<h3 id="navigation" tabindex="-1">Navigation</h3>
<p>För att länka mellan sidorna du skapat hittills så kan du bygga en navigation. Ett sätt att göra det är att skapa en separat Nunjucks fil som innehåller navigationen. Skapa en ny fil i <code>src/_includes</code> och kalla den för <code>navigation.njk</code>. I filen kan du lägga till följande innehåll.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>nav</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Hem<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/om/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Om<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>nav</span><span class="token punctuation">></span></span></code></pre>
<p>Nu kan du lägga till navigationen i <code>base.njk</code>.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
    {% include "navigation.njk" %}
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>{{ title }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span>
    {{ content | safe }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span></code></pre>
<pre class="language-css"><code class="language-css"><span class="token selector">nav > ul</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">gap</span><span class="token punctuation">:</span> 1rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="data" tabindex="-1">Data</h3>
<p>Eleventy kan även använda något som kallas för datafiler. I datafiler så kan du spara data som kan användas i templaterna. Datafiler läses in från mappen <code>_data</code> automatiskt av Eleventy, likt <code>_includes</code>. Skapa mappen <code>src/_data</code> och en fil i den. Kalla filen för <code>navigation.json</code>. I filen kan du lägga till följande innehåll.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">[</span>
    <span class="token punctuation">{</span>
        <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"Hem"</span><span class="token punctuation">,</span>
        <span class="token property">"url"</span><span class="token operator">:</span> <span class="token string">"/"</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">{</span>
        <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"Om"</span><span class="token punctuation">,</span>
        <span class="token property">"url"</span><span class="token operator">:</span> <span class="token string">"/om/"</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">]</span></code></pre>
<p>Datafiler kan vara i formatet JSON, YAML eller JavaScript. I exemplet ovan så används JSON. Nu kan du använda datafilen i templaten. Uppdatera <code>navigation.njk</code> för att använda datafilen.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>nav</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
        
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>nav</span><span class="token punctuation">></span></span></code></pre>
<p>Det som sker i templaten är att variabeln <code>navigation</code> fylls med data från datafilen. Med hjälp av <a href="https://mozilla.github.io/nunjucks/templating.html#for" target="_blank" rel="noopener">Nunjucks for loop</a> så skapas sedan en lista med länkar.</p>
<h2 id="avslutning-och-forts%C3%A4ttning" tabindex="-1">Avslutning och fortsättning</h2>
<p>Detta är en introduktion till att bygga statiska sidor med Eleventy som verktyg. Mer information och instruktioner kommer då du får lära dig att utöka innehållet på sidan.</p>
<p>Jag har valt att dela upp innehållet för att sidan inte skulle bli för lång. Du kan läsa mer om hur du kan utöka sidan i <a href="/posts/eleventy-del-tva/">Eleventy, del två</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Två punkt noll</title>
        <link href="https://jensa.dev/sv/posts/tva-punkt-noll/"/>
        <updated>Mon, 20 Jun 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/tva-punkt-noll/</id>
        <content type="html"><![CDATA[<h2 id="vad" tabindex="-1">Vad</h2>
<p>Version 2.0ish av den här sidan/bloggen. Jag rullade tillbaks versionen i package filen, minns inte ens varför den var på 2.1. Hursomhelst, det är good enough nu och fungerar (peppar, trä, osv.).</p>
<h2 id="varf%C3%B6r" tabindex="-1">Varför</h2>
<p>Jag har jobbat med att redesigna den här sidan inför att jag ska fylla den med nytt material (hah). En stor del av arbetet har såklart varit den faktiska designen, men jag har också velat arbeta med att separera delarna och skapa komponenteter för dem.</p>
<p>Att arbeta med komponenter började med en önskan att lära mig <a href="https://storybook.js.org/" target="_blank" rel="noopener">Storybook</a> som i sin tur tog fart när jag läste, <a href="https://multiline.co/mment/2022/01/eleventy-storybook/" target="_blank" rel="noopener">Using Storybook with Nunjucks components in Eleventy</a>, en post om att kombinera Eleventy, Nunjucks och Storybook. Mycket intressant men tiden har inte riktigt funnits för att prova det fullt ut. Så det har inte realiserats i den här versionen. Jag har även samlat på mig ideer från <a href="https://twitter.com/5t3ph" target="_blank" rel="noopener">5t3ph</a>s videos om att skapa ett <a href="https://www.twitch.tv/collections/vZqWNnVE2hZPAg" target="_blank" rel="noopener">design system med Eleventy</a>.</p>
<p>Det kan vara så att jag hittar pepp och inspiration i teknik, system och design.</p>
<h2 id="hur" tabindex="-1">Hur</h2>
<ul>
<li>Ny design, inspirerad av den inte så nya <a href="https://en.wikipedia.org/wiki/Neue_Grafik" target="_blank" rel="noopener">Neue Grafik</a>.</li>
<li>Färger, hämtade från <a href="https://github.com/ayu-theme/vscode-ayu" target="_blank" rel="noopener">Ayu</a> temat. Detta för att jag valde färger, började med koddemos, prism-tema färger och blev ledsen. Så färgerna blev genomgående från koden.</li>
<li>Komponenter, som är macros, som förmodligen borde bli mindre komponenter, som inte märks för användaren.</li>
<li>Ny css, modernare, grid och annan struktur.</li>
<li>Projekt.</li>
<li>Koddemos, detta var en av grundkraven jag började jobba ifrån då jag som nämnt tänkte flytta innehåll jag skriver.</li>
<li>Kategorier, tänkt att hjälpa med det ovannämnda materialet.</li>
</ul>
]]></content>
    </entry>
    
    
    <entry>
        <title>Koddemos</title>
        <link href="https://jensa.dev/sv/posts/koddemos/"/>
        <updated>Fri, 20 May 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/koddemos/</id>
        <content type="html"><![CDATA[<h2 id="varf%C3%B6r" tabindex="-1">Varför</h2>
<p>Min tanke är att kunna använda den här sidan för att hosta kodexempel som jag använder i mina kurser. För närvarande är materialet på ett antal olika sidor:</p>
<ul>
<li><a href="https://jensadev.github.io/wu-exempel/" target="_blank" rel="noopener">Exempel för webbutveckling</a></li>
<li><a href="https://jens-andreasson.gitbook.io/webbserverprogrammering/" target="_blank" rel="noopener">Webbserverprogrammering</a></li>
<li><a href="https://jens-andreasson.gitbook.io/webbutveckling/" target="_blank" rel="noopener">Webbutveckling</a></li>
</ul>
<p>En del av materialet är i behov av uppdatering så när jag började titta på det och arbetade med en uppdaterad version av exempel för webbutveckling så kändes det som en rimlig ambition att flytta koden hit.</p>
<h2 id="hur" tabindex="-1">Hur</h2>
<p>Det är inte första eller sista gången jag vänder mig till Eleventy-communityn för  att hitta kod, exempel och ideer. Basen till koden för mina demos kommer från <a href="https://11ty.rocks/posts/eleventy-templating-static-code-demos/" target="_blank" rel="noopener">11ty.rocks</a> en sida skapad av <a href="https://twitter.com/5t3ph" target="_blank" rel="noopener">Stephanie Eckles</a>.</p>
<p>Det första exemplet som jag arbetade med är kopierat från den sidan. Jag har dock bytt ut <code>&lt;details&gt;</code> elementet för att skapa tabbar. Jag ville kunna använda tabbar för koden eftersom jag vill kunna visa html, css och javascript.</p>
<p><strong>Jag har tagit bort demos funktion och använder codepen istället.</strong></p>
<p>Lösningen kombinerar en massa olika delar, på den här sidan laddas exemplet med följande kod.</p>
<pre class="language-twig"><code class="language-twig"><span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">set</span> demo <span class="token operator">=</span> collections<span class="token punctuation">.</span>orderedDemos <span class="token operator">|</span> getDemo<span class="token punctuation">(</span><span class="token string"><span class="token punctuation">"</span>CSS Centering<span class="token punctuation">"</span></span><span class="token punctuation">)</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> demo<span class="token punctuation">.</span>data<span class="token punctuation">.</span>title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> demo<span class="token punctuation">.</span>data<span class="token punctuation">.</span>title <span class="token delimiter punctuation">}}</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span>
  <span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> demo<span class="token punctuation">.</span>templateContent <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>article</span><span class="token punctuation">></span></span>
</code></pre>
<p>Vi väljer önskad demo och laddar den från collections. Det mesta har dock skett innan detta då demosar sparas som njk poster på sidan som i sin tur använder en partial för att formateras. Denna funktionalitet kommer från 5t3phs kod.</p>
<pre class="language-twig"><code class="language-twig">---
title: "CSS Centering"
order: 1
date: 2021-03-31
templateEngineOverride: njk, md
---

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">set</span> description <span class="token delimiter punctuation">%}</span></span>

**Put down the CSS centering jokes**! This modern update is often the solution you're looking for to solve your centering woes.

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endset</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">set</span> css <span class="token delimiter punctuation">%}</span></span>
.centering {
    display: grid;
    place-content: center;
    min-height: 30vh;
}
.centering span {
    padding: .5em;
    outline: 2px solid;
}
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endset</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">set</span> javascript <span class="token operator">=</span> <span class="token boolean">false</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">set</span> html <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>centering<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">></span></span>Feeling Centered<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endset</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">include</span> <span class="token string"><span class="token punctuation">"</span>partials/components/demo/template.njk<span class="token punctuation">"</span></span> <span class="token delimiter punctuation">%}</span></span>
</code></pre>
<p>Den utökning jag har gjort ses i javascript/html delarna och formatteringen och för  att se det behöver vi titta på templaten. Den här templaten är uppmärkt med en brappiljard raw taggar för att den faktiska koden ska synas, oklart om allt är rätt men här är den i alla fall. Jag är tveksam till att den går att kopiera eller att använda eftersom den är otroligt petig med whitespace, så om du är intresserad av att faktiskt använda det, kolla på <a href="https://github.com/jensadev/jensa.dev/tree/main/src/_includes/partials/components/demo/template.njk" target="_blank" rel="noopener">demo template</a>.</p>
<pre class="language-twig"><code class="language-twig"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>demo<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%-</span> <span class="token tag-name keyword">if</span> <span class="token operator">not</span> hideDemo <span class="token delimiter punctuation">-%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">></span></span><span class="token style"><span class="token language-css"><span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> css <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%-</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">-%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> javascript <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"><span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> javascript <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%-</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">-%}</span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> <span class="token operator">not</span> hideDescription <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> description <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>demo__code<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> html <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>html-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tab<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">highlight</span> <span class="token string"><span class="token punctuation">"</span>html<span class="token punctuation">"</span></span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> html <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endhighlight</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> css <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>css-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tab<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">highlight</span> <span class="token string"><span class="token punctuation">"</span>css<span class="token punctuation">"</span></span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> css <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endhighlight</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> javascript <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>js-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tab<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>

<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">highlight</span> <span class="token string"><span class="token punctuation">"</span>javascript<span class="token punctuation">"</span></span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> javascript <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endhighlight</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tabs group<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> html <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#html-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>HTML<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> css <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#css-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>CSS<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">if</span> javascript <span class="token delimiter punctuation">%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#js-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Javascript<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">%}</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%-</span> <span class="token tag-name keyword">if</span> <span class="token operator">not</span> hideDemo <span class="token delimiter punctuation">-%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>demo__playground<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{{-</span> html <span class="token operator">|</span> safe <span class="token delimiter punctuation">}}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token twig language-twig"><span class="token delimiter punctuation">{%-</span> <span class="token tag-name keyword">endif</span> <span class="token delimiter punctuation">-%}</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">></span></span><span class="token style"><span class="token language-css">
<span class="token selector">#html-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>:target ~ .tabs li > a[href="#html-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>"],
#css-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>:target ~ .tabs li > a[href="#css-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>"],
#js-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>:target ~ .tabs li > a[href="#js-<span class="token twig language-twig"><span class="token delimiter punctuation">{{</span> title <span class="token operator">|</span> slugify <span class="token delimiter punctuation">}}</span></span>"]</span> <span class="token punctuation">{</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-light<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">border-color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--color-dark<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">></span></span></code></pre>
<p>Ganska så rörigt, tack och lov så behöver en kanske inte vara och peta i filen. Den sista delen är kopplat till tabbarna och krävs för att styla den aktiva tabben. Tabbarna är gjorda helt med css och förlitar sig på target selectorn genom fragment länkar (#id). Detta gör även att om jag vill länka till en bit av koden så använder jag helt enkelt en fragment länk.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">.tab</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.tab:target</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.tab:not(:target)</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="slutsats" tabindex="-1">Slutsats</h2>
<p>Jag är hyffsat nöjd och det fungerar. Nu är det good enough och fokuset ligger på innehåll.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Webbserver-programmering</title>
        <link href="https://jensa.dev/sv/posts/webbserver-programmering/"/>
        <updated>Mon, 16 May 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/webbserver-programmering/</id>
        <content type="html"><![CDATA[<p>För kursen Webbserverprogrammering 1 på gymnasienivå har jag valt tekniken, eller stacken, Node, Mysql och WSL. Jag anser att den är relevant och bra plattform att utgå ifrån. Den här stacken har även fördelen att använda javascript backend, för då använder vi samma programmeringsspråk som för frontend. Hosting, som sista pusselbit, gör vi med molntjänster.</p>
<p>Det här är en introduktion till de olika delarna du behöver förbereda för att kunna arbeta med kursen. Här hittar du installationsinstruktioner, länkar och exempel.</p>
<h2 id="windows-subsystem-for-linux" tabindex="-1">Windows Subsystem for Linux</h2>
<p>WSL låter oss köra Linux under Windows. Det är i min mening helt fantastiskt och med det slipper vi dual-boot och massa annan ondska. Det är enkelt och smidigt (värdeord, relativt i sammanhanget, för alternativen är mer komplexa) och ger dig tillgång till bash i en terminal under Windows. Det här är nästa steg om du tidigare kört <a href="https://git-scm.com/downloads" target="_blank" rel="noopener">Git-Bash</a>, du kommer känna igen dig men nu har du en faktiskt Linux installation under windows. Med WSL2 går det även att köra grafiska program om du så önskar.</p>
<p>Att kunna åtminstone lite bash och kunna arbeta i terminalen är viktigt för att arbeta med kod anser jag. Det ger en ökad förståelse för datorns struktur, kommandon och funktion. Med WSL kan du välja vilken <a href="https://en.wikipedia.org/wiki/Linux_distribution" target="_blank" rel="noopener">Linux dist</a> du vill köra, men till att börja med rekommenderar jag Ubuntu (finns i Microsoft store). Leta efter Long term support (LTS) versionen.</p>
<p><strong>Innan du kör igång så se till att du har kört windows update, startat om och repeterat detta ett antal gånger.</strong></p>
<ul>
<li><a href="https://docs.microsoft.com/en-us/windows/wsl/install" target="_blank" rel="noopener">Installera WSL</a></li>
</ul>
<p>När du installerar WSL/Ubuntu så var noga när du skapar en användare, glöm inte bort att sätta ett lösenord (som du kommer ihåg).</p>
<p>Du kan nu med fördel även passa på att installera Windows terminal, som är ett mycket trevligare alternativ än windows standard-terminal.</p>
<ul>
<li><a href="https://docs.microsoft.com/en-us/windows/terminal/install" target="_blank" rel="noopener">Windows Terminal</a></li>
</ul>
<p>När installationen är slutförd så behöver du uppdatera din dist (tänk windows update), kör du Ubuntu så använder du följande kommandon i terminalen.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt</span> update
<span class="token function">sudo</span> <span class="token function">apt</span> upgrade</code></pre>
<p>I bash kan du sedan skapa en code mapp där du kan spara dina projekt.</p>
<pre class="language-bash"><code class="language-bash"><span class="token builtin class-name">cd</span>
<span class="token function">mkdir</span> code
<span class="token builtin class-name">cd</span> code
<span class="token function">ls</span> <span class="token parameter variable">-la</span></code></pre>
<p><picture><source type="image/webp" srcset="/img/gCW7f5-7dS-300.webp 300w, /img/gCW7f5-7dS-600.webp 600w, /img/gCW7f5-7dS-900.webp 900w" sizes="Skärmdump av WSL"><img alt="Skärmdump av WSL" loading="lazy" decoding="async" src="/img/gCW7f5-7dS-300.jpeg" width="900" height="486" srcset="/img/gCW7f5-7dS-300.jpeg 300w, /img/gCW7f5-7dS-600.jpeg 600w, /img/gCW7f5-7dS-900.jpeg 900w" sizes="Skärmdump av WSL"></picture></p>
<h3 id="n%C3%A5gra-anv%C3%A4ndbara-bash-kommandon" tabindex="-1">Några användbara bash kommandon</h3>
<table>
<thead>
<tr>
<th>Kommando</th>
<th>Beskrivning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sudo KOMMANDO</code></td>
<td>Kör kommando som superuser</td>
</tr>
<tr>
<td><code>ls</code></td>
<td>Listar innehållet i en mapp, <code>-la</code> för att se allt</td>
</tr>
<tr>
<td><code>cd MAPP</code></td>
<td>Går till en annan mapp, enbart cd tar dig till din /home mapp</td>
</tr>
<tr>
<td><code>mkdir MAPP</code></td>
<td>Skapar en ny mapp</td>
</tr>
<tr>
<td><code>touch FIL</code></td>
<td>Skapar en fil</td>
</tr>
<tr>
<td><code>rm FIL/MAPP</code></td>
<td>Tar bort en fil, ska du ta bort en mapp med filer lägg till <code>-rf</code>, recursive force</td>
</tr>
<tr>
<td><code>cp FIL DEST</code></td>
<td>Kopierar en fil till angiven destination</td>
</tr>
<tr>
<td><code>mv FIL DEST</code></td>
<td>Flyttar en fil till angiven destination</td>
</tr>
<tr>
<td><code>cat FIL</code></td>
<td>Läser en fil och skriver ut den</td>
</tr>
<tr>
<td><code>history</code></td>
<td>Listar historik, du kan seadan köra kommandot från historiken med !nummer</td>
</tr>
</tbody>
</table>
<h2 id="nodejs" tabindex="-1">Nodejs</h2>
<p><a href="https://nodejs.org/en/" target="_blank" rel="noopener">Node</a> är en javascript runtime byggd på Chrome V8s javascript motor. Med ramverket <a href="https://expressjs.com/" target="_blank" rel="noopener">Express</a> blir Node den webbserver (för utveckling) vi använder. Tillsammans med Node så kommer vi att använda oss av <a href="https://www.npmjs.com/" target="_blank" rel="noopener">Node packet manager (npm)</a>. NPM är en populär pakethanterare för javascript-utveckling och ett viktigt verktyg att känna till och kunna använda, det gäller både front och back-end.</p>
<p>För att installera och köra Node samt NPM så använder vi oss utan Node Version Manager(nvm).</p>
<ul>
<li><a href="https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl#install-nvm-nodejs-and-npm" target="_blank" rel="noopener">Installera NVM och Node</a></li>
</ul>
<h2 id="mysql" tabindex="-1">MySQL</h2>
<p>För att arbeta med databas så använder vi <a href="https://www.mysql.com/" target="_blank" rel="noopener">MySQL</a>. SQL är ett språk för relationsdatabaser, MySQL är en hanterare för detta. Vi använder SQL som databasspråk för att det är en välanvänd standard och det blir din introduktion till databaser och hur de fungerar. Vi kör MySQL för att det är en av de vanligaste databashanterarna.</p>
<p>MySQL körs med en server på din eller en annan dator. Du kan sedan använda en klient för att koppla upp dig till databasservern. För att installera MySQL server och klient kör.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> mysql-server mysql-client</code></pre>
<p>WSL startar inte alltid upp MySQL servern korrekt när det startas, för att starta om/upp servern använder du följande kommando. Om det inte fungerar, testa att starta om din dator och prova sedan igen.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">service</span> mysql restart</code></pre>
<p>Med servern igång kan du skapa en databasanvändare för den. Detta måste göras som superuser (säkerhet). För att skapa en användare behöver du koppla upp dig till databasservern från användaren root, för att göra det kör du kommandot som <a href="https://sv.wikipedia.org/wiki/Sudo" target="_blank" rel="noopener">sudo</a>.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">sudo</span> mysql <span class="token parameter variable">-u</span> root</code></pre>
<p><picture><source type="image/webp" srcset="/img/xL5pSFfvrH-300.webp 300w, /img/xL5pSFfvrH-600.webp 600w, /img/xL5pSFfvrH-900.webp 900w" sizes="Skärmdump av MySQL-klienten. Notera att trots varningen så är restarten av servern [  OK  ], vid fel så står det inte OK."><img alt="Skärmdump av MySQL-klienten" loading="lazy" decoding="async" src="/img/xL5pSFfvrH-300.jpeg" width="900" height="487" srcset="/img/xL5pSFfvrH-300.jpeg 300w, /img/xL5pSFfvrH-600.jpeg 600w, /img/xL5pSFfvrH-900.jpeg 900w" sizes="Skärmdump av MySQL-klienten. Notera att trots varningen så är restarten av servern [  OK  ], vid fel så står det inte OK."></picture></p>
<p>Väl inne i MySQL klienten så behöver du skapa en användare. Kör du följande kommando för att skapa en user med alla rättigheter, det är en fungerande lösning för lokal utveckling, men inte att rekommendera i en produktionsmiljö. Kom ihåg att byta ut <code>username</code> och <code>password</code>.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">USER</span> <span class="token string">'username'</span><span class="token variable">@'localhost'</span> IDENTIFIED <span class="token keyword">BY</span> <span class="token string">'password'</span><span class="token punctuation">;</span>
<span class="token keyword">GRANT</span> <span class="token keyword">ALL</span> <span class="token keyword">PRIVILEGES</span> <span class="token keyword">ON</span> <span class="token operator">*</span><span class="token punctuation">.</span><span class="token operator">*</span> <span class="token keyword">TO</span> <span class="token string">'username'</span><span class="token variable">@'localhost'</span><span class="token punctuation">;</span>
FLUSH <span class="token keyword">PRIVILEGES</span><span class="token punctuation">;</span></code></pre>
<p>Vi kommer senare att gå igenom vad dessa kommandon faktiskt gör i SQL.</p>
<p>När du skapat användaren så avsluta med <code>exit</code>. Du kan nu ansluta till databasen igen med din skapade användare.</p>
<pre class="language-bash"><code class="language-bash">mysql <span class="token parameter variable">-u</span> USERNAME <span class="token parameter variable">-p</span></code></pre>
<p>Väl inne i klienten så kan du prova att skapa en databas för kursen. Om det fungerar så svara klienten med <code>QUERY OK</code>. Du kan sedan välja att visa en lista över dina databaser på servern med kommandot <code>SHOW</code>.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">DATABASE</span> webbserver<span class="token punctuation">;</span>
<span class="token keyword">SHOW</span> <span class="token keyword">databases</span><span class="token punctuation">;</span></code></pre>
<h2 id="visual-studio-code" tabindex="-1">Visual studio code</h2>
<p>Från bash under WSL så kan du starta Visual studio code från den aktuella mappen, jag rekommenderar att du gör det för att hela tiden vara i ditt projekts folder. För att starta VSCode i den aktuella mappen skriver du <code>code .</code>. Det här är även viktigt för att det startar Visual studio codes remote till ditt VSCode (första gången så installerar den ett tillägg innan det startar). Du kan se att du är uppkopplad till WSL i nedre vänstra hörnet av VSCode.</p>
<p><picture><source type="image/webp" srcset="/img/mCxyA1abhj-300.webp 300w, /img/mCxyA1abhj-600.webp 600w" sizes="100vw"><img alt="WSL connect" loading="lazy" decoding="async" src="/img/mCxyA1abhj-300.jpeg" width="600" height="54" srcset="/img/mCxyA1abhj-300.jpeg 300w, /img/mCxyA1abhj-600.jpeg 600w" sizes="100vw"></picture></p>
<p>Om det strular så kan du också dubbelkolla att du har installerat VScodes extension för WSL, du hittar den på <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl" target="_blank" rel="noopener">Marketplace</a>.</p>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>Förhoppningsvis har all installation gått bra och du har nu en fungerande utvecklarmiljö. Om något har strulat så hoppas jag att du har läst felmeddelanden, upprepat och läst texterna för att hitta vad du har missat.</p>
<p>Fortsättning följer.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>SQL</title>
        <link href="https://jensa.dev/sv/posts/sql/"/>
        <updated>Mon, 16 May 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/sql/</id>
        <content type="html"><![CDATA[<h2 id="innan-du-b%C3%B6rjar" tabindex="-1">Innan du börjar</h2>
<p>SQL skrivs som frågor (querys). SQL frågor skrivs ofta med <code>VERSALER</code> för kommandon och gemener för parametrar. Detta är dock inget krav då MySQL inte gör en skillnad på stora och små bokstäver (förutom i vissa fall, typ databasnamn).</p>
<h2 id="en-databas" tabindex="-1">En databas</h2>
<p>För att använda en databas behöver den först skapas (om den nu inte finns) och sedan väljas. För att skriva en query som skapar en databas skriver du:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">DATABASE</span> my_database<span class="token punctuation">;</span></code></pre>
<p>Om du arbetat med tidigare <a href="/posts/webbserver/#mysql">instruktioner</a> från det avsnittet, har du kanske en databas kallad <code>webbserver</code>. I så fall kan du använda den med <code>USE</code>.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">USE</span> webbserver<span class="token punctuation">;</span></code></pre>
<p><picture><source type="image/webp" srcset="/img/s9k8jmkhJ--300.webp 300w, /img/s9k8jmkhJ--600.webp 600w, /img/s9k8jmkhJ--900.webp 900w" sizes="Så här kan det se ut när du skapar en ny databas och tabell."><img alt="Skärmdump av MySQL-klienten" loading="lazy" decoding="async" src="/img/s9k8jmkhJ--300.jpeg" width="900" height="489" srcset="/img/s9k8jmkhJ--300.jpeg 300w, /img/s9k8jmkhJ--600.jpeg 600w, /img/s9k8jmkhJ--900.jpeg 900w" sizes="Så här kan det se ut när du skapar en ny databas och tabell."></picture></p>
<h2 id="tabeller" tabindex="-1">Tabeller</h2>
<p>En SQL databas innehåller i sin tur en eller flera tabeller.</p>
<p>För att skapa en tabell i databasen så används <code>CREATE</code> kommandot men för att skapa en table så behöver vi ange minst ett fält för databasen. Vi passar även på att specificera teckenkodningen som utf8mb4 (vilket är det “vanliga” utf-8).</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> tabellnamn <span class="token punctuation">(</span>id <span class="token keyword">INT</span> <span class="token keyword">UNSIGNED</span> <span class="token keyword">AUTO_INCREMENT</span><span class="token punctuation">,</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">ENGINE</span> <span class="token operator">=</span> <span class="token keyword">innodb</span>
    <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span> <span class="token operator">=</span> utf8mb4<span class="token punctuation">;</span></code></pre>
<p>Inspektera tabellen med <code>DESCRIBE</code>.</p>
<pre><code>DESCRIBE tabellnamn;

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int unsigned | NO   | PRI | NULL    | auto_increment |
+-------+--------------+------+-----+---------+----------------+
1 row in set (0.00 sec)
</code></pre>
<h3 id="datatyper" tabindex="-1">Datatyper</h3>
<p>I tabellen ovan ser vi att <code>id</code> är av typen <code>int unsigned</code>. Detta betyder att det är ett heltal (int) som inte kan vara negativt (unsigned).</p>
<p>I MySQL finns det ett antal olika datatyper. Här är några vanliga:</p>
<ul>
<li><code>int</code> - ett heltal</li>
<li><code>varchar(0)</code> - en sträng, max 255 tecken</li>
<li><code>text</code> - en längre sträng</li>
<li><code>date</code> - ett datum</li>
<li><code>datetime</code> - ett datum och tid</li>
<li><code>timestamp</code> - ett datum och tid</li>
</ul>
<h3 id="auto-increment" tabindex="-1">Auto increment</h3>
<p>I tabellen ovan ser vi att <code>id</code> har <code>auto_increment</code> som extra. Detta betyder att varje gång vi lägger till en ny rad i tabellen så kommer <code>id</code> att öka med ett. Detta är ett sätt att skapa ett unikt id för varje rad i tabellen.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Testa med JS</title>
        <link href="https://jensa.dev/sv/posts/testa-med-js/"/>
        <updated>Sat, 14 May 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/testa-med-js/</id>
        <content type="html"><![CDATA[<p>Min utgångspunk blev en kort en artikel, <a href="https://www.albertgao.xyz/2017/05/24/how-to-test-expressjs-with-jest-and-supertest/" target="_blank" rel="noopener">How to test Express.js…</a> om att testa <a href="https://expressjs.com/" target="_blank" rel="noopener">Express</a> med <a href="https://jestjs.io/" target="_blank" rel="noopener">Jest</a> och <a href="https://www.npmjs.com/package/supertest" target="_blank" rel="noopener">Supertest</a>. Jag hade dock inte något behov av babel, så jag installerade följande:</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> --save-dev jest supertest supertest-session</code></pre>
<p>Testen skapades i mappen <code>__tests__</code>. Eftersom det jag önskade testa var setup, routes, session och databas så delade jag upp testen i olika filer. Filerna numrerades för att få dem att köras i ordning (det finns säkert andra sätt att göra detta på).</p>
<p>Exempel på ett första test:</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'../app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> request <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'supertest'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">'1. Setup'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">'GET / '</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
        <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">'should return a 200 response'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
            expect<span class="token punctuation">.</span><span class="token function">assertions</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span>app<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">expect</span><span class="token punctuation">(</span>response<span class="token punctuation">.</span>statusCode<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Testet är skapat för att se om eleverna fått igång sin app/server. Här är det viktigt att notera att supertest kör <code>app.js</code>, för att starta upp testservrar. Jag har kört <a href="https://www.npmjs.com/package/express-generator" target="_blank" rel="noopener">Express-generator</a> för att scaffolda projektet och när npm startar http-servern så används filen <code>bin/www</code> som i sin tur startar <code>app.js</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token comment">/* bin/www */</span>
<span class="token keyword">var</span> server <span class="token operator">=</span> http<span class="token punctuation">.</span><span class="token function">createServer</span><span class="token punctuation">(</span>app<span class="token punctuation">)</span><span class="token punctuation">;</span>
server<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Det är viktigt att förstå att det inte blir riktigt samma process som när du kör igång din egen utvecklarserver och vissa problem kan manifisteras som inte annars märks. Till exempel som att din databaspool ligger och puttrar, din session inte är bortplockad, promises ligger och väntar och så vidare.<br>
Detta visar sig i att Jest spottar ur sig meddelandet,</p>
<blockquote>
<p>Jest has detected the following 1 open handle potentially keeping Jest from exiting</p>
</blockquote>
<p>En googling eller tre på området gav ingen nyttig information och anledningen till detta är (tror jag) att felet inte är Jests, utan en brist på förståelse för processen som Jest kör.</p>
<h2 id="l%C3%B6sning" tabindex="-1">Lösning</h2>
<p><strong>Se till att städa efter dig!</strong> För det här projektet använder jag <a href="https://www.npmjs.com/package/mysql2" target="_blank" rel="noopener">mysql2</a> för databas-kopplingen och dess funktion för en connection pool med promises. Den städar upp connections, men den lämnar även poolen öppen för nyttjande. Detta ledde till att Jest inte avslutades. För att åtgärda det så behövde jag stänga poolen när jag var klar med testerna, i mina tester (något som jag inte kan göra i min serverkod, då stängs poolen som faktiskt behöver vara öppen).</p>
<p>Så för teardown efter alla tester körts så använder jag funktionen afterAll och stänger poolen.</p>
<pre class="language-js"><code class="language-js"><span class="token function">afterAll</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">await</span> pool<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>För att testa databasen så är även <code>beforeAll()</code> viktigt att känna till så att du kan skapa users eller liknande. Jest har mer om dessa funktioner i dokumentationen, <a href="https://jestjs.io/docs/setup-teardown" target="_blank" rel="noopener">Setup and Teardown</a>.</p>
<p>Att använda både setup och teardown blev även aktuellt för att kunna testköra sessions på servern. Här valde jag att använda paketet Express-session. Det skapar en server likt supertest som du kan testa mot.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">let</span> authenticatedSession<span class="token punctuation">;</span>
<span class="token function">beforeAll</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> testSession <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">session</span><span class="token punctuation">(</span>app<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">await</span> testSession<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string">'/login'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token operator">...</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    authenticatedSession <span class="token operator">=</span> testSession<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Med det på plats så används authenticatedSession i alla test som behöver sessions. Men glöm inte att avsluta sessionen om Jest inte avslutar korrekt.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">await</span> authenticatedSession<span class="token punctuation">.</span><span class="token function">destroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<h2 id="avslutning" tabindex="-1">Avslutning</h2>
<p>Så det var en lärdom från att skriva lite tester, förstå hur din kod körs och hur testerna faktiskt fungerar. Min ambition ör att det ska bli mer tester kommande läsår både på <a href="https://www.ntigymnasiet.se/program/informations-och-medieteknik/umea/" target="_blank" rel="noopener">teknikprogrammet</a> och på <a href="https://www.ntigymnasiet.se/program/mjukvarudesign/umea/" target="_blank" rel="noopener">te4</a>. Jag har tänkt det förut, men för min det gäller det att komma över tröskeln så jag är bekväm med det. Med det sagt så är jag osäker på vad som är god praxis gällande tester i större utsträckning.</p>
<p>För att skriva många av testerna till det här projektet så visade sig GitHub Copilot vara en hjälpsam parprogrammerare, med otaliga förslag om att testa input element efter input element.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>2022, uppdateringar</title>
        <link href="https://jensa.dev/sv/posts/2022-uppdateringar/"/>
        <updated>Sun, 13 Mar 2022 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/2022-uppdateringar/</id>
        <content type="html"><![CDATA[<h2 id="mat" tabindex="-1">Mat</h2>
<p>Ett projekt som legat i träda en längre period är min mat sida, <a href="https://mat-jensnti.vercel.app/" target="_blank" rel="noopener">måltidsloggen</a>. Projektet skapades ursprungligen för att jag skulle lära mig mer om en api, men också för att lära mig om <a href="https://reactjs.org/" target="_blank" rel="noopener">React</a>. Anledningen till att sidan varit nere är att databasservern (mysql) som den använde inte längre var tillgänglig. <a href="https://github.com/jensadev/mat" target="_blank" rel="noopener">Måltidsloggens api/backend</a> är hostat med <a href="https://www.heroku.com/" target="_blank" rel="noopener">Heroku</a> och Herokus mysql add-on är sådär. Heroku fungerar mycket enklare med deras postgres add-on, så jag tog mig tiden att uppdatera sidans api till att köra postgres. Att migrera till postgres var inte en stor grej eftersom sidan använder en ORM, <a href="https://sequelize.org/" target="_blank" rel="noopener">Sequelize</a>.</p>
<p>När väl api/backend backend delen var uppdaterad så kunde jag fixa frontend delen. Frontenden använder <a href="https://nextjs.org/" target="_blank" rel="noopener">Next.js</a> och är hostat på <a href="https://vercel.com" target="_blank" rel="noopener">Vercel</a>. Eftersom sidan varit nere så krävdes det en hel del uppdateringar av frontend-koden för att den skulle fungera igen (Next kräver lintning bla.) men det ordnade sig.</p>
<p>Så måltidsloggen är live igen och dess TODO-lista är gigantisk. Det kliar i fingrarna att använda nya lärdomar.</p>
<h2 id="popup" tabindex="-1">Popup</h2>
<p>Jag har uppdaterat sidan med bland annat en “cookie-consent” popup, detta av den enkla anledningen att sidan faktiskt sparar info i din localstorage (färgschema) men även använder <a href="https://analytics.google.com/analytics/web/" target="_blank" rel="noopener">Google Analytics</a> för trafik. Utöver det så finns fonter på typekit.</p>
<p>Själva designen på elementet kommer från mitt arbetet med <a href="https://programmering.jensa.dev/" target="_blank" rel="noopener">TOD sidorna</a> där jag tyckte det var viktigt att få med.</p>
<h2 id="tod" tabindex="-1">TOD</h2>
<p>Just TOD sidorna har fått en del uppmärksamhet då jag försökte skapa en alternativ uppgifts-layout, detta efter lite pedagogiskt prat med min kollega <a href="https://github.com/KajSchmidt" target="_blank" rel="noopener">Kaj</a>. En av grundtankarna med att dela upp ett material i teman, områden och delar är att kunna gömma information för eleven. Detta för att hjälpa eleven med sina val, sitt fokus och helt enkelt inte visa för mycket.</p>
<p>Den existerande designen på TOD använder accordions för att begränsa informationen som visas. Det har dock visat sig att eleverna går vilse i strukturen och det fortfarande är mycket att ta in. För att underlätta skapades två nya funktioner:</p>
<ul>
<li>Popup med “Du arbetade senast med” som leder användaren till senaste området</li>
<li>Toggle för att byta layout, till en struktur med boxar som visar teman och områden. Eleven ser alltså inte delarna.</li>
</ul>
<p>Den kompaktare layouten med boxar utgår från en spelinspirerad tanke om skilltrees. Resultatet blev sådär och är i högsta grad ett work in progress, men det fungerar och används på <a href="https://programmering.jensa.dev/" target="_blank" rel="noopener">programmering.jensa.dev</a>.</p>
<h2 id="todo" tabindex="-1">TODO</h2>
<h3 id="den-h%C3%A4r-sidan" tabindex="-1">Den här sidan</h3>
<p>Listan är lång men jag tvingar mig att faktiskt skriva text om det först. 🙂</p>
<h3 id="webbexempel" tabindex="-1">Webbexempel</h3>
<p>Jag har börjat samla en del elevarbeten på webbplatser utifrån en “sidmall” jag skapade för att visa exempel i webbutvecklingen. Sidan är byggd med eleventy men jag valde att hosta den på GitHub pages, en test. I nuläget finns <a href="https://jensadev.github.io/wu-exempel/" target="_blank" rel="noopener">wu-exempel</a> hostad där men en tanke jag hade var att flytta exempel hit, till bloggen. Av den anledningen påbörjade jag arbetet med att kunna sandboxa exempel i denna kod, men det blev inte riktigt färdigt.</p>
<h3 id="elevarbeten%2C-spel" tabindex="-1">Elevarbeten, spel</h3>
<p>Jag har nu kört ett moment med speldesign i flera år och varje år samlat elevernas spel. Det har varje år blivit en ny typ av sida och i slutändan har inte något samlats i en form som går att överblicka, men nu finns det något där. Eftersom jag hade exempel-sidan så valde jag att återanvända den. <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a> är så perfekt för den här typen av arbete och att hosta det på Netlify gör alltihopet lite enklare.</p>
<p>Kolla gärna in <a href="https://spelsite.netlify.app/" target="_blank" rel="noopener">spelsiten med elevarbeten</a>.</p>
<h3 id="elevarbeten%2C-gymnasiearbete" tabindex="-1">Elevarbeten, gymnasiearbete</h3>
<p>I kollegiet har vi de senaste åren arbetat hårt tillsammans med eleverna för att höja kvaliten på elevernas gymnasiearbeten. Gymnasiearbetet på teknik-programmet ska vara en förberedels inför högre studier. Eleverna ska efter arbetet ha god koll på hur en  genomför en vetenskaplig studie.</p>
<p>För att visa upp detta arbete och hjälpa eleverna så kopierade jag spel-sites mallen för att använda med gymnasiearbeten. <a href="https://gyarb.netlify.app/2022/" target="_blank" rel="noopener">GYARB sidan</a> är dock än så länge enbart ett skelett.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Advent of code 2021</title>
        <link href="https://jensa.dev/sv/posts/advent-of-code-2021/"/>
        <updated>Tue, 07 Dec 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/advent-of-code-2021/</id>
        <content type="html"><![CDATA[<p>Julkalendrar är en stor grej och att koda som en kan vara det med. <a href="https://adventofcode.com/" target="_blank" rel="noopener">Advent of code</a> är en årligt återkommande samling pussel som löses med hjälp av programmering. Svårigheten är varierande och du löser det du klarar av och hinner med.</p>
<p>Tidigare år har jag bara löst något enstaka pussel och sällan i december, men i år har jag kommit igång bättre och fått ett antal ⭐. Det är kul och utmanande och hittills en typ av programmering jag inte så ofta ägnar mig åt.</p>
<p>Så testa, jag rekommenderar det verkligen!</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Linta</title>
        <link href="https://jensa.dev/sv/posts/linta/"/>
        <updated>Mon, 06 Dec 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/linta/</id>
        <content type="html"><![CDATA[<p>Jag tänkte först att jag skulle skriva den här posten för ett par veckor sedan, men tiden försvann till annat. Ibland är det bra att låta saker och texter gro, det är en lärdom från den här sidan, men i det här fallet har jag nog till viss del glömt vad jag ville skriva.</p>
<p>Grunden till en post om att linta var att jag fixat <a href="https://eslint.org/" target="_blank" rel="noopener">ESLint</a> för <a href="https://github.com/jensadev/tod" target="_blank" rel="noopener">Tema, Område, Del</a> och den här sidan. Som ett minnesmärke till skrivandet hade jag lämnat följande rad.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i --save-dev prettier eslint eslint-config-prettier eslint-plugin-prettier eslint-plugin-simple-import-sort</code></pre>
<h2 id="eslint" tabindex="-1">ESLint</h2>
<p>Är ett kod-verktyg/-hjälpmedel som analyserar din kod och hjälper dig att hitta problem. ESLint kan fixa problem men kan även ställa till det en del. Att följa reglerna som ESLint har kan tyckas vara självklart utan ett verktyg, men det är ett hjälpmedel och när det börjar bli mycket kod så kan det hjälpa.</p>
<p>ESLint har en uppsjö plugins och regelsystem så det är bara att välja och vraka. Det kan vara lite pill att få till konfigurationen, men jämfört med andra val så tycker jag det är värt det.</p>
<p>Min konfiguration för det här projektet ser ut som följer.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"env"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">"browser"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
        <span class="token property">"node"</span><span class="token operator">:</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">"extends"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"eslint:recommended"</span><span class="token punctuation">,</span> <span class="token string">"plugin:prettier/recommended"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">"parserOptions"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">"ecmaVersion"</span><span class="token operator">:</span> <span class="token number">8</span><span class="token punctuation">,</span>
        <span class="token property">"sourceType"</span><span class="token operator">:</span> <span class="token string">"module"</span><span class="token punctuation">,</span>
        <span class="token property">"impliedStrict"</span><span class="token operator">:</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">"plugins"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"prettier"</span><span class="token punctuation">,</span> <span class="token string">"simple-import-sort"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token property">"rules"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">"prettier/prettier"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"error"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token property">"usePrettierrc"</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token property">"simple-import-sort/imports"</span><span class="token operator">:</span> <span class="token string">"error"</span><span class="token punctuation">,</span>
        <span class="token property">"simple-import-sort/exports"</span><span class="token operator">:</span> <span class="token string">"error"</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>Den använder både node och browser som environment, eftersom <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a> är javascript i node och det finns även med script som körs i webbläsaren. Utöver det har jag valt eslint:recommended inställningen samt att jag kör formatteringen från <a href="https://prettier.io/" target="_blank" rel="noopener">Prettier</a> med <a href="https://www.npmjs.com/package/eslint-plugin-prettier" target="_blank" rel="noopener">eslint-plugin-prettier</a>.</p>
<h2 id="prettier" tabindex="-1">Prettier</h2>
<p>Som komplement till ESLint använder jag <a href="https://prettier.io/" target="_blank" rel="noopener">Prettier</a> som är ett annat kod-verktyg/-hjälpmedel för formattering. Tillsammans så tycker jag att de<br>
i de flesta fallen fungerar riktigt bra.</p>
<p>Prettier har relativt lite inställningar och går fort att få igång. Det fungerar även utmärkt utan ESLint och går att konfigurera i VSCode eller med en konfigurationsfil. För VSCode finns det en extension, <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" target="_blank" rel="noopener">Prettier formatter for VSCode</a>.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"semi"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">"tabWidth"</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span>
    <span class="token property">"printWidth"</span><span class="token operator">:</span> <span class="token number">80</span><span class="token punctuation">,</span>
    <span class="token property">"singleQuote"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token property">"trailingComma"</span><span class="token operator">:</span> <span class="token string">"es5"</span>
<span class="token punctuation">}</span></code></pre>
<h2 id="automatisera" tabindex="-1">Automatisera</h2>
<p>Prettier kan köras på save i VSCode om så önskas, alternativt är att formattera manuellt (SHIFT+ALT+F).<br>
För att linta alltihop så går det att köra från npm i terminalen, i <code>package.json</code>.</p>
<pre class="language-json"><code class="language-json"><span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    ...
    <span class="token property">"lint"</span><span class="token operator">:</span> <span class="token string">"eslint --fix ."</span><span class="token punctuation">,</span>
    <span class="token property">"format"</span><span class="token operator">:</span> <span class="token string">"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc"</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre>
<p>Glöm inte att lägga till <code>node_modules</code> i <code>.eslintignore</code>.</p>
<h2 id="problem" tabindex="-1">Problem</h2>
<p>Inte helt oväntat så stötte jag på en del problem med att få igång verktygen jag valt för sidorna. Ett av problemen var som tidigare nämnt att ESLint validerade både browser och node kod. Det blev även lite konflikt kring ECMAversion.</p>
<p>Ett område som jag inte riktigt har en bra lösning på är dock arbetet med Eleventy. Formatteringen av Markdown går sådär och ibland så saboteras front-matter fullständigt. I andra fall så blir <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks</a> filer en ren röra och det går inte överhuvudtaget med kod-snuttar i Nunjucks.</p>
<p>Tyvärr så sviker mig minnet något här och denna post blev främst en en lista över vad jag använder. Kanske användbart.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Localstorage och slutuppgifter</title>
        <link href="https://jensa.dev/sv/posts/localstorage-och-slutuppgifter/"/>
        <updated>Tue, 16 Nov 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/localstorage-och-slutuppgifter/</id>
        <content type="html"><![CDATA[<p>Jag har tidigare skrivit om kurswebbsystemet jag byggt, <a href="/tag/tod">Tema, område, del</a>. Det är ett ständigt work in progress (vad är inte det) och jag har inte riktigt fått till uppgiftsfunktionen som jag önskat.</p>
<p>TOD grunden finns hostad som <a href="https://silly-bhaskara-09612e.netlify.app/" target="_blank" rel="noopener">Ämnestitel</a> på Netlify och för den som vill kolla på koden (eller skapa en egen kurswebb) finns det ett <a href="https://github.com/jensadev/tod" target="_blank" rel="noopener">template repo</a>.</p>
<h2 id="systemet-som-fanns" tabindex="-1">Systemet som fanns</h2>
<p>Tidigare så fanns ingen data i systemet över vilka teman, områden, delar och uppgifter som existerade. Detta för att jag inte ville att en sådan data skulle behöva skapas manuellt. Systemet är skapat med iden att det ska vara tämligen enkelt att köra igång en kurswebb och fokus ska ligga på att skriva innehåll (sen kanske det är ofrånkomligt att viss programmeringskunskap krävs).</p>
<p>Det fungerade så att när en användare checkade av en uppgift som klar så skapades ett objekt för att identifiera detta i localstorage. När sidan för en del (med uppgifterna) sedan laddas så kontrolleras då uppgiften i fråga och checkboxens status uppdaterades.<br>
Startsidan fungerade så att alla element för de olika teman, områden och delarna laddades från sidans DOM. Sedan kollade scriptet om en progress finns i localstorage. Om uppgiften finns sparad så skapas stjärnorna samt en progressbar.</p>
<p><picture><source type="image/webp" srcset="/img/AA1MdE6Uhe-300.webp 300w, /img/AA1MdE6Uhe-600.webp 600w, /img/AA1MdE6Uhe-900.webp 900w" sizes="Illustration, startsida - progress."><img alt="Skärmdump av startsidan på programmeringswebben." loading="lazy" decoding="async" src="/img/AA1MdE6Uhe-300.jpeg" width="900" height="258" srcset="/img/AA1MdE6Uhe-300.jpeg 300w, /img/AA1MdE6Uhe-600.jpeg 600w, /img/AA1MdE6Uhe-900.jpeg 900w" sizes="Illustration, startsida - progress."></picture></p>
<h3 id="slutuppgifter" tabindex="-1">Slutuppgifter</h3>
<p>Jag ville kunna lägga till slutuppgifter i systemet, så att en elev skulle kunna checka av sin kunskap för ett område. Men jag ville inte bara lägga till en del för slutuppgiften och byta template på denna. Anledningen till detta är att en del av den pedagogiska tanken med systemet är att systemet ska dölja uppgifter tills eleven är redo för dem. Det kan tillochmed vara så att en elev aldrig ska se uppgiften i fråga, då det kanske inte är relevant för hen.</p>
<p>Eftersom webbsidan i sig inte hade information kring antalet delar med uppgifter i varje område så blev det mer eller mindre omöjligt att dölja slutuppgiften. Jag började med att försöka få till det med den tidigare strukturen, men det blev inte bra.</p>
<h2 id="skapa-json" tabindex="-1">Skapa JSON</h2>
<p>Lösningen blev att automatisera skapandet av en JSON fil för uppgiftsstrukturen. För detta använde jag en transform, grunden för detta kommer från <a href="https://github.com/andy-piccalilli/hylia-preview" target="_blank" rel="noopener">Hylia</a>, 11ty starter kit.<br>
Detta är en funktion som körs efter det mesta andra i 11ty. Den tuggar sig igenom all HTML och spottar ut något på andra sidan, i det här fallet en JSON-fil. Min mall för JSON-filens utformning såg ut ungefär såhär.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
    <span class="token property">"subject"</span><span class="token operator">:</span> <span class="token string">"amnestitel"</span><span class="token punctuation">,</span>
    <span class="token property">"themes"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            <span class="token property">"theme"</span><span class="token operator">:</span> <span class="token string">"tema"</span><span class="token punctuation">,</span>
            <span class="token property">"areas"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
                <span class="token punctuation">{</span>
                    <span class="token property">"area"</span><span class="token operator">:</span> <span class="token string">"område"</span><span class="token punctuation">,</span>
                    <span class="token property">"parts"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
                        <span class="token punctuation">{</span>
                            <span class="token property">"part"</span><span class="token operator">:</span> <span class="token string">"del"</span><span class="token punctuation">,</span>
                            <span class="token property">"assignments"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
                                <span class="token punctuation">{</span>
                                    <span class="token property">"assignment"</span><span class="token operator">:</span> <span class="token string">"uppgift-1"</span><span class="token punctuation">,</span>
                                    <span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"basic"</span><span class="token punctuation">,</span>
                                    <span class="token property">"completed"</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
                                    <span class="token property">"date"</span><span class="token operator">:</span> <span class="token null keyword">null</span>
                                <span class="token punctuation">}</span>
                            <span class="token punctuation">]</span>
                        <span class="token punctuation">}</span>
                    <span class="token punctuation">]</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">]</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre>
<p>JSON-filen fick sedan stå som mall för det objekt sidan skapar i localstorage. Nu kunde detta localstorage object skaps direkt när sidan laddas och status för uppgifterna hanteras. Detta ledde i sin tur till att det mesta behövde skrivas om. Eftersom allt är skrivet i javascript utan något ramverk så måste allt uppdateras, hanteras och fixas. Jag kunde fortsätta använda en del av mina DOM-metoder, men för biten med localstorage så skrev jag en klass.<br>
Progress delen för framsidan och uppgiftshanteringen fick skrivas om, men i slutändan så blev det bra mycket bättre.</p>
<h2 id="refactor" tabindex="-1">Refactor</h2>
<p>Mitt första utkast av koden använde sig av <a href="https://lodash.com/" target="_blank" rel="noopener">lodash</a> för att leta sig igenom objekt och arrayer med objekt i arrayer och så vidare. Lodash fick åka med som en dependecy och jag tänkte inte så mycket mer på det. Detta tills jag började bli klar och såg att min javascript bundle plötsligt blivit gigantisk. Jag trixade en del med <a href="https://rollupjs.org/" target="_blank" rel="noopener">rollup</a> för att få ordning på detta, men lyckades inte. Huruvida detta beror på min förmåga eller rollup/lodash låter jag vara osagt, men jag bestämde mig vilketsom för att lösa problemet utan lodash.</p>
<h3 id="find" tabindex="-1">Find</h3>
<p>Att göra detta kom att resultera i att ganska mycket kod skrevs på annat sätt, men här nedan följer ett exempel på hur jag bytte ut <a href="https://lodash.com/docs/4.17.15#find" target="_blank" rel="noopener">_find</a> mot <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find" target="_blank" rel="noopener">find</a>. Nu är dess funktion inte riktigt jämförbar, lodash gör mer, men för mitt behov så behövde jag inte mer heller.</p>
<pre class="language-js"><code class="language-js">result <span class="token operator">=</span> <span class="token function">_find</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'name'</span><span class="token punctuation">,</span> theme<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>storage<span class="token punctuation">.</span>themes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// med lodash</span>
result <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>storage<span class="token punctuation">.</span>themes<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span> <span class="token operator">=></span> t<span class="token punctuation">.</span>name <span class="token operator">===</span> theme<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// utan lodash</span></code></pre>
<p>Lärdomen av detta är att det kan vara bättre att spendera tid för att förbättra sin kod och använda det som finns än att använda genvängen som är ett bibliotek. Med det sagt så har lodash sin funktion och jag lyckades inte helt ersätta det.</p>
<h3 id="merge" tabindex="-1">Merge</h3>
<p>När 11ty bygger sidan så skapas JSON-objektet för strukturen. När sidans struktur, eller uppgifter ändras, så vill jag uppdatera objektet i localstorage med ändringarna. Det ska ske, men såklart inte skriva över användarens sparade progress. För att göra detta så önskade jag göra en merge av två objekt. Denna merge skulle även ta hänsyn och titta i arrayer och annat.</p>
<p>Att koda detta kändes i stunden som övermäktigt så jag letade på <a href="https://copilot.github.com/" target="_blank" rel="noopener">Copilot</a> och <a href="https://stackoverflow.com/" target="_blank" rel="noopener">Stackoverflow</a>. I slutändan så hittade jag en rekursiv funktion i denna <a href="https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6#gistcomment-3889214" target="_blank" rel="noopener">gist</a> som nästan gör det jag vill, så jag är inte riktigt färdig med min refaktor.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">merge</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">source<span class="token punctuation">,</span> target</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token punctuation">[</span>key<span class="token punctuation">,</span> val<span class="token punctuation">]</span> <span class="token keyword">of</span> Object<span class="token punctuation">.</span><span class="token function">entries</span><span class="token punctuation">(</span>source<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">typeof</span> val <span class="token operator">===</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">object</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>target<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                target<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">val<span class="token punctuation">.</span>__proto__<span class="token punctuation">.</span>constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token function">merge</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> target<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            target<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> target<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> merge <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<h2 id="slutsats" tabindex="-1">Slutsats</h2>
<p>Detta var lärorikt och bra att göra. Jag är nöjd med systemet och jag tror att resultatet både fungerar bättre och är mer robust.</p>
<p>Att skriva javascript på det här sättet tycker jag är både roligt och lärorikt, men det är lagomt besvärligt (i den här skalan). Projektet i sig kanske är på gränsen till att behöva ett ramverk och det är absolut inget konstigt att använda sig av det för att skapa en webb med dessa funktioner, det kan tillochmed vara så att det är att föredra.</p>
<p>Att använda sig av ett ramverk skulle dock ta bort en av de grundläggande ideerna med systemet, att det ska räcka med att skriva lite MD filer för att skapa en kurswebb.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Länkfarm</title>
        <link href="https://jensa.dev/sv/posts/lankfarm/"/>
        <updated>Thu, 30 Sep 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/lankfarm/</id>
        <content type="html"><![CDATA[<p>När jag skrev föregående inlägg så formulerade sig en feature i mitt huvud som jag önskade på den här sidan. Ett sätt att sammanställa alla länkar i texten till en lista i slutet av dokumentet.</p>
<p>För att skapa en lista med det så använde jag den redan existerande transform (HTML koden parsas och spottas ut på nytt) som körs när Eleventy bygger den här sidan.</p>
<p>Jag skrev och testade följande javascript. Alla länkar på sidan hämtas, loopas igenom och koden skapar listan.</p>
<p>Självklart så dök det upp undantag för vissa sidor där jag inte önskade detta och tyvärr så är transform funktionen ett senare steg i 11tys byggprocess så det kan inte använda <code>collections.posts</code>.</p>
<pre class="language-js"><code class="language-js">    <span class="token keyword">const</span> articleLinks <span class="token operator">=</span> <span class="token punctuation">[</span>
        <span class="token operator">...</span>document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'main .post a'</span><span class="token punctuation">)</span>
    <span class="token punctuation">]</span><span class="token punctuation">;</span>

        <span class="token keyword">if</span> <span class="token punctuation">(</span>articleLinks<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">const</span> pageTitle <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.site-intro__title'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">// what if I write the post Om... something</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>pageTitle <span class="token operator">!==</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>pageTitle<span class="token punctuation">.</span>textContent<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">'Om'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">const</span> list <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'.post__harvest-links'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">const</span> externalLinks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

                articleLinks<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">anchor</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>anchor<span class="token punctuation">.</span>href<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">'https'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                        <span class="token keyword">const</span> listItem <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'li'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">const</span> listLink <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'a'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        listLink<span class="token punctuation">.</span>href <span class="token operator">=</span> anchor<span class="token punctuation">.</span>href<span class="token punctuation">;</span>
                        listLink<span class="token punctuation">.</span>textContent <span class="token operator">=</span> anchor<span class="token punctuation">.</span>textContent<span class="token punctuation">;</span>
                        listLink<span class="token punctuation">.</span>target <span class="token operator">=</span> <span class="token string">'_blank'</span><span class="token punctuation">;</span>
                        listLink<span class="token punctuation">.</span>rel <span class="token operator">=</span> <span class="token string">'noopener'</span><span class="token punctuation">;</span>
                        listItem<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>listLink<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        list<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>listItem<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        externalLinks<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>anchor<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Rent tekniskt är det en lösning som funkar, vilket är okej. Men rent skrivtekniskt så tvingar det mig att skriva mina texter så att länkarna faktiskt är en del av dem. Det får mig att skriva in mina källor och referenser i texten, snarare än att bara klistra dit en <em>Läs mer</em> länk i slutet. Det är bra.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Arbeta med Eleventy i klassrummet</title>
        <link href="https://jensa.dev/sv/posts/arbeta-med-eleventy-i-klassrummet/"/>
        <updated>Wed, 29 Sep 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/arbeta-med-eleventy-i-klassrummet/</id>
        <content type="html"><![CDATA[<p>Efter en vår och sommar där jag använt <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a> för egen hand till flera projekt så har jag valt att börja använda Eleventy i klassrummet. Utifrån vad Eleventy är tycker (<a href="https://www.11ty.dev/docs/" target="_blank" rel="noopener">static site builder/generator</a>) jag att det passar utmärkt att använda i kursen <a href="https://www.skolverket.se/undervisning/gymnasieskolan/laroplan-program-och-amnen-i-gymnasieskolan/gymnasieprogrammen/amne?url=1530314731%2Fsyllabuscw%2Fjsp%2Fsubject.htm%3FsubjectCode%3DWEU%26tos%3Dgy&amp;sv.url=12.5dfee44715d35a5cdfa92a3" target="_blank" rel="noopener">Webbutveckling 2</a> (länken fungerar eventuellt, <a href="https://www.skolverket.se/" target="_blank" rel="noopener">Skolverket</a> kör random på sina länkar en gång i veckan).</p>
<p>Eleventy är tillräckligt tillgängligt för att eleverna ska kunna använda det och startsträckan är hanterbar. Jag använder <a href="https://docs.microsoft.com/en-us/windows/wsl/install" target="_blank" rel="noopener">Windows Subsystem Linux</a> (eleverna får installera och använda) i min undervisning för att arbeta med <a href="https://nodejs.org/" target="_blank" rel="noopener">Node</a> i <a href="https://www.skolverket.se/undervisning/gymnasieskolan/laroplan-program-och-amnen-i-gymnasieskolan/gymnasieprogrammen/amne?url=1530314731%2Fsyllabuscw%2Fjsp%2Fsubject.htm%3FsubjectCode%3DWES%26tos%3Dgy&amp;sv.url=12.5dfee44715d35a5cdfa92a3" target="_blank" rel="noopener">Webbserverprogrammering 1</a> (jag tycker inte riktigt att Windows-versionen av Node/npm är något att ha + att det är rätt bra att kunna använda bash). Eleventy blir således ett utmärkt verktyg för att ta arbetet med HTML och CSS till nästa nivå och börja inkludera verktyg som <a href="https://www.npmjs.com/" target="_blank" rel="noopener">npm</a>, <a href="https://sass-lang.com/" target="_blank" rel="noopener">sass</a> och <a href="https://rollupjs.org/" target="_blank" rel="noopener">rollup</a> (eller en bundler av valfri sort).</p>
<p>Att arbeta med Eleventy mot <a href="https://www.netlify.com/" target="_blank" rel="noopener">Netlify</a> ger även en utökad förståelse för hosting och liknande tjänster. Jag har tidigare arbetat med hosting genom <a href="https://pages.github.com/" target="_blank" rel="noopener">GitHub pages</a>, så det är en naturlig progression. Att ha Netlify som hosting och att den triggar på pushes till main är även ett utmärkt sätt att få eleverna att arbeta i branches.</p>
<p>De första vi skapat är någon form av personlig sida, blog eller portfolio. Det är framförallt ett sätt att testa och prova Eleventy innan vi går vidare till ytterligare projekt. Självklart finns det där en tanke om att skriva och reflektera över eget lärande, men det är inget jag förväntar mig ta skruv.</p>
<p>Resultat och reflektion kring hur det har gått kommer.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Tema, område, del</title>
        <link href="https://jensa.dev/sv/posts/tema-omrade-del/"/>
        <updated>Sat, 31 Jul 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/tema-omrade-del/</id>
        <content type="html"><![CDATA[<p>I slutet av vårterminen 2021 så diskuterade jag tillsammans med min kollega Kaj över hur uppgifter, information och instruktioner skulle kunna utformas för att nå elever på ett så gott sätt som möjligt.<br>
Kaj hade delat upp kursens innehåll i teman, områden och delar. Där en del var ett begränsat område (till en sida) innehållandes information, instruktion och uppgift. Jag gillande upplägget och började fundera utifrån det.<br>
Det var i samband med detta som jag bestämde mig för att testa <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a> för att skapa en slags kurswebb.</p>
<p>Min testkurs blev <a href="https://www.skolverket.se/undervisning/gymnasieskolan/laroplan-program-och-amnen-i-gymnasieskolan/hitta-program-amnen-och-kurser-i-gymnasieskolan?url=-996270488%2Fsyllabuscw%2Fjsp%2Fsearch.htm%3FalphaSearchString%3DW%26searchType%3DFREETEXT%26searchRange%3DCOURSE%26subjectCategory%3D%26searchString%3Dwebbutveckling&amp;sv.url=12.5dfee44715d35a5cdfa8e7a" target="_blank" rel="noopener">Webbutveckling (obs sökning på skolverket)</a> och jag skapade ett system kring detta. Min kurswebb för <a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">Webbutveckling</a> är ofullständig, men gav mig en bas för att skapa en Eleventy template att använda.</p>
<h2 id="tod" tabindex="-1">TOD</h2>
<p><a href="https://github.com/jensadev/tod" target="_blank" rel="noopener">Projekt templaten</a> kom att döpas till TOD efter just tema, område, del(fiffigare namnförslag är välkomna). Så nu skriver jag om TOD här, eftersom jag nyss gått igenom sidan och gjort en rejäl uppdatering av den. Efter att ha skapat <a href="https://www.jensa.dev" target="_blank" rel="noopener">jensa.dev</a>, där du läser detta och sedan kört igenom <a href="/posts/learn-eleventy-from-scratch/">Learn eleventy from scratch</a> kursen så bestämde jag mig för att arbeta om vissa grunder på sidan.</p>
<ul>
<li>Skippa <a href="https://getbootstrap.com/" target="_blank" rel="noopener">Bootstrap</a></li>
<li>Skriva CSS med struktur och tanke</li>
<li>Bundla javascript</li>
</ul>
<p>Jag är hyfsat nöjd med slutresultatet och har lyckats halvera storleken på CSS och halvera storleken på JS. Förutom det så är Lighthouse poängen något bättre och jag har mer kontroll över alltihopa.</p>
<p><picture><source type="image/webp" srcset="/img/L7BaS0pwnk-300.webp 300w, /img/L7BaS0pwnk-416.webp 416w" sizes="Lighthouse score."><img alt="Skärmdump av Lighthouse score." loading="lazy" decoding="async" src="/img/L7BaS0pwnk-300.jpeg" width="416" height="152" srcset="/img/L7BaS0pwnk-300.jpeg 300w, /img/L7BaS0pwnk-416.jpeg 416w" sizes="Lighthouse score."></picture></p>
<h2 id="inneh%C3%A5ll" tabindex="-1">Innehåll</h2>
<p>Så nu när sidan är mer eller mindre klar(fix fix fix) handlar det främst om att skriva innehåll. Förhoppningsvis kan jag komma igång med det snart, men det tar emot att slita sig ur sommarlovslunken.<br>
När det är gjort så ska jag försöka uppdatera den här sidan med lite av det jag lärt mig.</p>
<p>Resultaten av arbetet finns att beskåda på <a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">Webbutveckling</a> och <a href="https://programmering.jensa.dev" target="_blank" rel="noopener">Programmering</a> och uppdateras kontinuerligt.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Github Copilot</title>
        <link href="https://jensa.dev/sv/posts/github-copilot/"/>
        <updated>Mon, 12 Jul 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/github-copilot/</id>
        <content type="html"><![CDATA[<p>Såhär två månader senare så kommer här en kort uppdatering.<br>
Copilot är roligt att använda. Det har visat sig intressant och kul att använda tillsammans med eleverna i klassrummet och reaktionen har hittills varit 🤯 från dem.</p>
<p>Copilot kan leverera kod efter kommentarer och fungerar förvånansvärt bra. Kanske är det inte riktigt parprogrammering, men det kan ersätta googlande och läsande av stack overflow i ett nafs. Det aktualiserar dock och visar supertydligt hur viktigt det är att förstå och granska koden som en använder.</p>
<p>Jag har fått tillgång till den tekniska förhandstitten och testat lite. Men vad är Copilot? GitHub själva beskriver det så här:</p>
<blockquote>
<p>GitHub Copilot is an AI pair programmer which suggests line completions and entire function bodies as you type. GitHub Copilot is powered by the OpenAI Codex AI system, trained on public Internet text and billions of lines of code.</p>
</blockquote>
<p>Min erfarenhet hittills är att det är helt ok, det känns inte banbrytande. Jag har dock inte kodat särskilt mycket, så det jag framförallt sett är autocompletion och vid något tillfälle har jag fått kod föreslagen med alternativ. Det känns som en naturlig utökning av intellisense.</p>
<p>Så i nuläget kan jag inte direkt säga att det känns som att par-programmera. Tillägget har potential och det är hjälpsamt.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Learn Eleventy from Scratch</title>
        <link href="https://jensa.dev/sv/posts/learn-eleventy-from-scratch/"/>
        <updated>Thu, 24 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/learn-eleventy-from-scratch/</id>
        <content type="html"><![CDATA[<p>Plötsligt händer det. I det <a href="../learn-css/">första inlägget</a> på bloggen skrev jag om Andy Bells <a href="https://web.dev/learn/css/" target="_blank" rel="noopener">Learn CSS</a> kurs. På sin webbplats <a href="https://piccalil.li/" target="_blank" rel="noopener">Piccalilli</a> har han även en kurs, <a href="https://piccalil.li/course/learn-eleventy-from-scratch/" target="_blank" rel="noopener">Learn Eleventy From Scratch</a>. Den kursen har tidigare har kostat pengar, men nu är den gratis.<br>
Alltså är det ett utmärkt tillfälle att lära sig mer om <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a>.</p>
<p><picture><source type="image/webp" srcset="/img/Lip2Br6umT-300.webp 300w, /img/Lip2Br6umT-600.webp 600w, /img/Lip2Br6umT-900.webp 900w" sizes="Skapa det här."><img alt="Skärmdump av det du skapar i kursen" loading="lazy" decoding="async" src="/img/Lip2Br6umT-300.jpeg" width="900" height="1079" srcset="/img/Lip2Br6umT-300.jpeg 300w, /img/Lip2Br6umT-600.jpeg 600w, /img/Lip2Br6umT-900.jpeg 900w" sizes="Skapa det här."></picture></p>
<p>Eleventy har snabbt blivit något jag verkligen gillar. I våras har jag gett mig i kast med <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue</a>, <a href="https://reactjs.org/" target="_blank" rel="noopener">React</a> och <a href="https://nextjs.org/" target="_blank" rel="noopener">Next.js</a> för att skapa en frontend till en separat backend. Resultatet av det finns på min <a href="https://github.com/" target="_blank" rel="noopener">GitHub</a> och på <a href="https://mat.jensa.dev/" target="_blank" rel="noopener">Måltidsloggen</a>.</p>
<p>I slutändan så är jag inte övertygad, jag gillar det inte så värst mycket och tycker att mycket av det det gör är omständligt. Ska jag ranka dem så hamnar React sist. Next förbättrar dock utvecklarupplevelsen med React markant.<br>
Så utifrån vårens erfarenheter så känns Eleventy kul och inspirerande att jobba med (och ja, det är lite som att jämföra äpplen och apelsiner).</p>
<p>Hursomhelst så ser jag fram emot att köra igenom kursen nu i sommar och att använda den i höst förhoppningsvis.</p>
<p>Du hittar den här, <a href="https://piccalil.li/course/learn-eleventy-from-scratch/" target="_blank" rel="noopener">Learn Eleventy From Scratch</a>.</p>
<h2 id="erfarenheter-och-intryck" tabindex="-1">Erfarenheter och intryck</h2>
<p>Här är lite tankar efter att jag kört igenom kursen.<br>
Kursen är skapad i fyra moduler. Det är dock mer som tre, eftersom den fjärde är en wrap-up.</p>
<h3 id="modul-1" tabindex="-1">Modul 1</h3>
<p>Den första modulen introducerar Eleventy och hur en kan arbeta med det. Det finns mycket bra här att lära. Det är lärorikt tycker jag att se Andys tänkt kring Front matter och hur det kan användas. Att spara flera delar av en sida i front matter och sedan kombinera det på olika sätt är verkligen en styrka i Eleventy.</p>
<p>Det finns även mycket bra här kring användadet av <a href="https://mozilla.github.io/nunjucks/" target="_blank" rel="noopener">Nunjucks</a> för att på smarta sätt återanvända komponenter och skapa layouter.</p>
<h3 id="modul-2" tabindex="-1">Modul 2</h3>
<p>Efter att ha skapat sidans HTML kod i den första modulen så handlar denna om byggsystem. Jag hade inte testat att använd <a href="https://gulpjs.com/" target="_blank" rel="noopener">GULP</a> tidigare (i alla fall medvetet) och tycker att det var en mycket bra introduktion.</p>
<p>Den här sidan använder inte GULP, utan den byggs med <a href="https://www.npmjs.com/package/npm-run-all" target="_blank" rel="noopener">npm-run-all</a>, <a href="https://www.npmjs.com/package/cssnano" target="_blank" rel="noopener">cssnano</a>, <a href="https://www.npmjs.com/package/autoprefixer" target="_blank" rel="noopener">autoprefixer</a> och <a href="https://www.npmjs.com/package/postcss" target="_blank" rel="noopener">postcss</a>. Detta är något som jag plockade upp från <a href="https://twitter.com/5t3ph" target="_blank" rel="noopener">Stephanie Eckles</a> utmärkta startkurs, <a href="https://egghead.io/courses/build-an-eleventy-11ty-site-from-scratch-bfd3" target="_blank" rel="noopener">Build An Eleventy (11ty) Site From Scratch</a>.</p>
<p>Men efter att ha testat att bygga med GULP så kommer jag nog att prova det framöver då det ger en del extra kontroll (tror jag).</p>
<p>Den här modulen innehåller även ett avsnitt kring att arbeta med bilder. Jag använder <a href="https://www.npmjs.com/package/@11ty/eleventy-img" target="_blank" rel="noopener">@11ty/eleventy-img</a> paketet för den här sidan för att automatisera optimeringen av bilder, så GULP behövs inte för detta. Men det är ett alternativ.</p>
<h3 id="modul-3" tabindex="-1">Modul 3</h3>
<p>I den här modulen är det dags för CSS och för att få sidan att se ut som något. Här får Andy verkligen visa upp det han kan och sidan introducerar steg för steg <a href="https://cube.fyi/" target="_blank" rel="noopener">CUBE CSS</a> och tänket bakom det. Andy visar även sitt verktyg för utilities, <a href="https://www.npmjs.com/package/gorko" target="_blank" rel="noopener">Gorko</a>.<br>
Det finns mycket bra att lära här kring CSS och en metodologi för det som jag tycker känns rimlig, men jag är nog inte riktigt där i att använda den för något eget.</p>
<p>Om du letat efter en bra introduktion till CSS_grid så finns det även här. CSS-grid är något som jag inte alls gett mig in på, flexbox har gjort det jag önskat hittills. Men det är nog något som kommer ändras efter detta.</p>
<p>Att få se sidan skapas och bli till med CSS är riktigt kul och lärorikt. Det finns massor med bra tips i detta avsnitt och slutresultatet innehåller mycket design-element som jag gillar.</p>
<p>Avsnittet levererar även flera läsvärda länkar och jag har samlat en del i slutet av den här texten.</p>
<h2 id="slutsats" tabindex="-1">Slutsats</h2>
<p>Kursens form är i stilen av att kod presenteras, förklaras och sedan upprepas det. Du ställas alltså inte inför några direkta problem att lösa. Det fungerar bra för mig, men det är verkligen viktigt att skapa en egen produkt utifrån kursens innehåll för att befästa och använda det.</p>
<p>Det har hänt en del kring Eleventy sen kursen skapades. Nyheter och plugins har lagts till, men det påverkar inte kursens kvalité och innehåll.</p>
<p>Så slutligen kan jag <em>verkligen</em> rekommendera kursen för att komma igång med statiska sidor och Eleventy.</p>
<p>⭐⭐⭐⭐⭐</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Sommarlov</title>
        <link href="https://jensa.dev/sv/posts/sommarlov/"/>
        <updated>Wed, 23 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/sommarlov/</id>
        <content type="html"><![CDATA[<p>För min del så finns det alltid en tanke om ett antal projekt under <s>sommaren</s> hela året. Jag ser fram emot att förkovra mig och koda under min lediga tid. Så i arbetet med det lär det dyka upp saker att skriva om.</p>
<p>Projekten som väntar är 🚧</p>
<ul>
<li><a href="https://github.com/jensadev/tod" target="_blank" rel="noopener">Tema, område, del</a>, en form av kurswebb med tydlig struktur. Detta är ett template-repo att bygga ifrån. Byggt med Eleventy.</li>
<li><a href="https://webbutveckling.jensa.dev" target="_blank" rel="noopener">Webbutveckling 1</a>, byggt med TOD och en första test.</li>
<li><a href="https://github.com/jensadev/mat-nextjs" target="_blank" rel="noopener">Måltidsloggen</a>, bygg i Next.js med en tillhörande <a href="https://github.com/jensadev/mat" target="_blank" rel="noopener">backend</a>.</li>
<li><a href="https://piccalil.li/course/learn-eleventy-from-scratch/" target="_blank" rel="noopener">Learn Eleventy From Scratch</a> och använda det.</li>
</ul>
<p>Men nog om det, lite om den här sidans hosting och publicering.</p>
<h2 id="netlify" tabindex="-1">Netlify</h2>
<p>Hittills har jag hostat alla projekt jag skrivit i Eleventy på <a href="https://www.netlify.com/" target="_blank" rel="noopener">Netlify</a>. Det kanske inte riktigt behövs, då en skulle kunna hosta det på <a href="https://github.com/" target="_blank" rel="noopener">GitHub</a> direkt med pages. En av skillnaderna blir att bygga det på Netlify vs lokalt och sedan pusha resultatet.</p>
<p>Men Netlify har fungerat utmärkt som sagt så vi kör på det. Det är även bra att öva på att inte arbeta i main.</p>
<h2 id="dom%C3%A4n" tabindex="-1">Domän</h2>
<p>Väl uppe så tänkte jag försöka koppla ihop det med min domän, <a href="https://www.jensa.dev" target="_blank" rel="noopener">jensa.dev</a>. Jag har än så länge enbart använt den till <a href="/projekt/maltidsloggen/">Måltidsloggen</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>CSS, namn och semantik</title>
        <link href="https://jensa.dev/sv/posts/css-namn-och-semantik/"/>
        <updated>Tue, 22 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/css-namn-och-semantik/</id>
        <content type="html"><![CDATA[<p>Jag har omformulerat texten till det här inlägget ett par gånger nu istället för att skriva flera. Kanske är det så att jag borde skriva ett inlägg mer som en artikel och låta den gro några dagar innan jag publicerar. Jag har även försökt att skriva så att texten kan bidra med lite förståelse och olika synpunkter, inte bara kasta ut min åsikt.</p>
<p>Det första utkastet handlade om BEM och det sättet att tänka kring CSS, men jag vet inte om jag riktigt är med på tåget. Jag har ofta använt <a href="https://getbootstrap.com/" target="_blank" rel="noopener">Bootstrap</a> för de projekt jag har gjort. Bootstrap är långt från BEM i sin utformning. Från Bootstrap har jag främst använt mig av de utility-klasser som finns. Positionering, grid och en grundläggande stil för forms. Ett bibliotek som Bootstrap är väldigt smidigt och fungerar utmärkt när en vant sig vid det.</p>
<p>Jag har tittat på <a href="https://tailwindcss.com/" target="_blank" rel="noopener">Tailwind</a>, men aldrig riktigt testat. Tailwind är väldigt mycket utility-klasser. Jag upplever det som ett steg för långt, även om jag verkligen kan uppskatta utility-klasser. Många som ondgör sig över Tailwind jämför det med att skriva inline css. Det är inte en helt rättvis jämförelse (mer om detta på <a href="https://css-tricks.com/if-were-gonna-criticize-utility-class-frameworks-lets-be-fair-about-it/" target="_blank" rel="noopener">CSS-tricks</a>).</p>
<h2 id="utility-first" tabindex="-1">Utility-first</h2>
<p>Det som Tailwind kommit att representera är att skriva CSS Utility-first.<br>
I ett <a href="(https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)">blogginlägg</a> från 2017 resonerar sig Adam Wathan fram till tänket bakom ramverket. Texten är väl värd att läsa. Jag tror att de flesta som arbetat med CSS kommer att känna igen sig i hans resonemang om hur CSS bör/ska/kan struktureras.</p>
<h2 id="bem" tabindex="-1">BEM</h2>
<p>Jag nämnde BEM tidigare i texten, det står för Block Element Modifier och är en metod för att namnge CSS i större projekt. Ordningen i BEM är tämligen sund och tydlig tycker jag.</p>
<ul>
<li>Block, en semantisk komponent</li>
<li>Element, en del som är beroende av blocket</li>
<li>Modifier, något som kan ändra blockets stil</li>
</ul>
<p>BEM försöker att <a href="https://www.smashingmagazine.com/2014/07/bem-methodology-for-small-projects/" target="_blank" rel="noopener">undvika cascade</a>, något som jag förstår poängen med. Cascade är dock en feature i CSS och något som bör användas anser jag.<br>
På den här sidan har jag försökt låna BEM liknande klassnamn i min CSS, men jag är ganska långt ifrån att följa reglerna.<br>
Läs mer om BEM i <a href="https://css-tricks.com/bem-101/" target="_blank" rel="noopener">BEM-101</a> på CSS-Tricks, för BEM har en del bra poänger det med.</p>
<h2 id="ett-exempel" tabindex="-1">Ett exempel</h2>
<p>Här nedan finns scss koden för <code>.post</code> klassen här på sidan. <code>.post</code> är ett semantiskt namn för vad det är. Klassen återfinns på ett <code>&lt;article&gt;</code> element.</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">.post </span><span class="token punctuation">{</span>
    <span class="token selector">h2, h3 </span><span class="token punctuation">{</span>
        <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">figure </span><span class="token punctuation">{</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span> 0<span class="token punctuation">;</span>
        <span class="token property">width</span><span class="token punctuation">:</span> 100vw<span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>11<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">margin-left</span><span class="token punctuation">:</span> 50%<span class="token punctuation">;</span>
        <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>-50%<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token selector">figcaption </span><span class="token punctuation">{</span>
            <span class="token property">padding-top</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>-1<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token property">font-style</span><span class="token punctuation">:</span> italic<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token selector">img, picture </span><span class="token punctuation">{</span>
        <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    ...
<span class="token punctuation">}</span></code></pre>
<p>I <code>.post</code> klassen så är ett antal andra element nästlade, headings, bilder osv. Eftersom dessa element är genererade av Eleventy så har jag valt att använda element-selektorer. Detta skapar då problemet att klassen med största sannolikhet inte går att återanvända, den blir väldigt specifik för denna sida.</p>
<p>Det går inte heller att återanvända koden för en figure, då den är specifik under <code>.post</code>. Den skulle behöva flyttas till en klass. Den upprepning är inte heller bra i enlighet med Don’t Repeat Yourself (DRY) principer. Koden för utfall (eng. <a href="https://en.wikipedia.org/wiki/Bleed_(printing)" target="_blank" rel="noopener">bleed</a>) även på <code>pre</code> elementet (som används för kod).</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector"><span class="token parent important">&amp;</span>__lead </span><span class="token punctuation">{</span>
    <span class="token property">font-family</span><span class="token punctuation">:</span> <span class="token variable">$serif</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector"><span class="token parent important">&amp;</span>__foot </span><span class="token punctuation">{</span>
    <span class="token property">padding-top</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">padding-bottom</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Sist finns det två klasser för delar i en <code>.post</code>. Tyvärr är bitar av det också återanvänt i <code>.pagination</code>.</p>
<p>Utöver det så laddas en del andra stilar kopplade till header- och image-elementen som ärvs med cascade. Det är även det som gör att marginaler och padding krävs på vissa ställen, då andra värden önskas.</p>
<h3 id="analys" tabindex="-1">Analys</h3>
<p>En stor del av den CSS på den här sidan faller i fällorna som Adam tar upp i sin artikel. Klassnamnen försöker vara semantiska, men klasserna i sig är inte tillräckligt generiska för att kunna återanvändas.<br>
Jag har lite BEM tänk där, vilket orsakar en del upprepning.</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">.post-list__list </span><span class="token punctuation">{</span>
    <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
    <span class="token property">padding-left</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
    <span class="token property">padding-right</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
    ...
<span class="token punctuation">}</span>

<span class="token selector">.tag-list </span><span class="token punctuation">{</span>
    <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">padding-left</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
    <span class="token property">padding-right</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Här är ett exempel som är ganska hemskt faktiskt. Men samtidigt så vill jag inte att elementet för tag-list ska ha klassen post-list, det känns rörigt och inte BEM. Det orsakar dock upprepning för att uppnå någorlunda semantiska klassnamn.<br>
En variant hade såklart kunnat vara att arbeta med utilities.</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">li </span><span class="token punctuation">{</span>
    <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.d-flex </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.px-0 </span><span class="token punctuation">{</span>
    <span class="token property">padding-left</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
    <span class="token property">padding-right</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Då hade min markup ändrats ganska avsevärt för att undvika upprepning i CSS-klasserna. Jag får samtidigt ett gäng CSS-klasser som jag kan återanvända.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tag-list<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tag-list d-flex px-0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span></code></pre>
<p>En annan variant är att skippa det semantiska och skapa en <code>.styled-list</code> klass som går att återanvända tillsammans med specifika och/eller utilities.</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">.styled-list </span><span class="token punctuation">{</span>
    <span class="token property">list-style</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">padding-left</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
    <span class="token property">padding-right</span><span class="token punctuation">:</span> 0rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.flex </span><span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">.flex-column </span><span class="token punctuation">{</span>
    <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>I det här fallet kanske klassen passar bättre som <code>.unstyled-list</code>. CSS-klassens namn blir inte lika specifikt semantisk, men frågan om det verkligen påverkar kodens läsbarhet. En vinner nog lite här och förlorar lite där.</p>
<h2 id="slutsats" tabindex="-1">Slutsats</h2>
<p>Jag tror jag landar någonstans i mitten, jag har en del utility men försöker skriva en del komponentstyrda CSS-regler. Jag känner ingen större lust att använda Tailwind och samtidigt så använder jag gärna Bootstrap för utility. Kanske är det så att det är dags att skriva mitt eget utility baserat på vad jag använder från Bootstrap, det vore nog rätt lärorikt.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Kodformattering</title>
        <link href="https://jensa.dev/sv/posts/kodformattering/"/>
        <updated>Mon, 21 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/kodformattering/</id>
        <content type="html"><![CDATA[<p>Att kunna skriva kodexempel och visa kod på den här sidan är ett måste. Som tur är så finns det tillgängligt med Eleventys <a href="https://www.11ty.dev/docs/plugins/syntaxhighlight/" target="_blank" rel="noopener">Syntax Highlight Plugin</a>. Det använder i sin tur <a href="https://prismjs.com/" target="_blank" rel="noopener">Prism</a> för att stila koden.</p>
<p>Att inkludera CSS för ett Prism-tema är sedan nästa steg. Detta följs av dilemmat kring att bli nöjd med helheten, Prism-temat och sidans stilar.<br>
Önskar en fler teman än Prisms standard, så finns <a href="https://github.com/PrismJS/prism-themes/blob/master/README.md" target="_blank" rel="noopener">Prism themes</a> GitHub repo.</p>
<p>Min tanke för den här sidan <s>är</s>/<s>var</s> att utgå från <a href="https://github.com/PrismJS/prism-themes/blob/master/themes/prism-ghcolors.css" target="_blank" rel="noopener">GitHubs</a> tema och sedan ändra. Vi <s>får se hur det går</s> kan nu se hur det gick.</p>
<h2 id="installation-och-konfiguration" tabindex="-1">Installation och konfiguration</h2>
<p>Installera först pluginet.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i @11ty/eleventy-plugin-syntaxhighlight</code></pre>
<p>Pluginet behöver sedan laddas i konfigurationen.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> syntaxHighlight <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'@11ty/eleventy-plugin-syntaxhighlight'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">eleventyConfig</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    eleventyConfig<span class="token punctuation">.</span><span class="token function">addPlugin</span><span class="token punctuation">(</span>syntaxHighlight<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>Sedan behöver Prisms css laddas, detta kan göras med lokal fil eller från CDN.</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span>
    <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span>
    <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/themes/prism.min.css<span class="token punctuation">"</span></span>
    <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sha512-tN7Ec6zAFaVSG3TpNAKtk4DOHNpSwKHxxrsiw4GHKESGPs5njn/0sMCUMl2svV4wo4BK/rCP7juYz+zx+l6oeQ==<span class="token punctuation">"</span></span>
    <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span>
    <span class="token attr-name">referrerpolicy</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>no-referrer<span class="token punctuation">"</span></span>
<span class="token punctuation">/></span></span>
<span class="token comment">&lt;!-- eller --></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/css/prism.css<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre>
<h2 id="eget-tema-och-stil" tabindex="-1">Eget tema och stil</h2>
<p>Fontstorleken behöver åtgärdas då den annars blev för stor för kodavsnitt.</p>
<pre class="language-css"><code class="language-css"><span class="token selector">.text-small</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>0<span class="token punctuation">)</span> <span class="token important">!important</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>Just fonten flyttade sedan in i ett eget Prism-tema. Koden här nedan formaterar “kod-styckena” i texten.</p>
<pre class="language-scss"><code class="language-scss"><span class="token property"><span class="token variable">$code-paths</span></span><span class="token punctuation">:</span> <span class="token punctuation">(</span>
    <span class="token property">1</span><span class="token punctuation">:</span> <span class="token function">polygon</span><span class="token punctuation">(</span>0 0<span class="token punctuation">,</span> 100% 2%<span class="token punctuation">,</span> 100% 98%<span class="token punctuation">,</span> 0% 100%<span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token property">2</span><span class="token punctuation">:</span> <span class="token function">polygon</span><span class="token punctuation">(</span>0 2%<span class="token punctuation">,</span> 100% 0<span class="token punctuation">,</span> 100% 100%<span class="token punctuation">,</span> 0 98%<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token selector">pre </span><span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100vw <span class="token important">!important</span><span class="token punctuation">;</span>
    <span class="token property">margin-left</span><span class="token punctuation">:</span> 50% <span class="token important">!important</span><span class="token punctuation">;</span>
    <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">translateX</span><span class="token punctuation">(</span>-50%<span class="token punctuation">)</span> <span class="token important">!important</span><span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">align-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    &amp;<span class="token punctuation">:</span><span class="token function">nth-of-type</span><span class="token punctuation">(</span>even<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token property">clip-path</span><span class="token punctuation">:</span> <span class="token function">map-get</span><span class="token punctuation">(</span><span class="token variable">$code-paths</span><span class="token punctuation">,</span> 1<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    &amp;<span class="token punctuation">:</span><span class="token function">nth-of-type</span><span class="token punctuation">(</span>odd<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token property">clip-path</span><span class="token punctuation">:</span> <span class="token function">map-get</span><span class="token punctuation">(</span><span class="token variable">$code-paths</span><span class="token punctuation">,</span> 2<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">code </span><span class="token punctuation">{</span>
        <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
        <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span>
        <span class="token property">margin-left</span><span class="token punctuation">:</span> auto <span class="token important">!important</span><span class="token punctuation">;</span>
        <span class="token property">margin-right</span><span class="token punctuation">:</span> auto <span class="token important">!important</span><span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token function">ms</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span> <span class="token important">!important</span><span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> 45.18rem <span class="token important">!important</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>Detta tog inte direkt hand om temat dock.</p>
<h2 id="slutresultat" tabindex="-1">Slutresultat</h2>
<p>Jag provade att skapa ett eget tema med en <a href="http://k88hudson.github.io/syntax-highlighting-theme-generator/www/" target="_blank" rel="noopener">generator</a> men blev inte så nöjd.<br>
Vad det blev i slutändan syns på sidan och kommer säkert att ändras. Jag utgick från <a href="https://github.com/PrismJS/prism-themes/blob/master/themes/prism-duotone-space.css" target="_blank" rel="noopener">Prism Duotone Space</a> för att få en enkel grund. Sedan ändrade jag på färgerna.</p>
<p>Här kan du titta på <a href="/css/prism.css">CSS-resultatet</a>.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Språk</title>
        <link href="https://jensa.dev/sv/posts/sprak/"/>
        <updated>Sun, 20 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/sprak/</id>
        <content type="html"><![CDATA[<p>Den här sidans syfte och funktion är kanske i främsta hand att jag ska skriva av mig lite och minnas, förstärka sådant jag arbetat med. Utifrån den tanken så känns det mest naturligt att skriva på svenska.</p>
<p>Sedan är det som vanligt en utmaning att översätta alla möjliga tekniska termer till svenska.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Att komma igång</title>
        <link href="https://jensa.dev/sv/posts/att-komma-igang/"/>
        <updated>Wed, 16 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/att-komma-igang/</id>
        <content type="html"><![CDATA[<p>Kanske är det inte så intressant för någon annan, men att skriva är en viktig och lärorik process som jag vill komma åt. Det blev min slutsats efter att ha läst lite kring att <a href="https://firstsiteguide.com/why-start-a-blog/" target="_blank" rel="noopener">starta en blog</a>. Nu skriver jag redan en hel del i mitt yrke, men innehållet på den här sidan är tänkt att hysa en annan form.</p>
<p>Eftersom jag är som jag är så började jag med den tekniska biten. Ett nytt repo, titta runt lite på teknik och fundera och grubbla.<br>
Jag har nyligen lärt mig lite <a href="https://11ty.dev" target="_blank" rel="noopener">Eleventy</a> och det har varit en väldigt trevlig erfarenhet. En bra utvecklar upplevelse (eng. developer experience, DX). Så att köra en blogg, eller personlig sida om en vill kalla det det med Eleventy kändes självklart. Jag började genast titta, gilla, undersöka, rata, kolla, och fundera på massor av olika <a href="https://www.11ty.dev/docs/starter/" target="_blank" rel="noopener">Eleventy-starters</a>, alla skapade av mer begåvade kodare än undertecknad. Utifrån det så började jag sätta ihop bitar och skriva CSS och… Sen stannade jag där, för att fixa med hela den biten är kul, engagerande och tillfredsställande.</p>
<blockquote>
<p>Men det som oftast saknas är innehållet.</p>
</blockquote>
<p>Så här sitter jag nu och tvingar mig själv att skriva lite innehåll, det handlar om att <a href="https://www.sarasoueidan.com/desk/just-write/" target="_blank" rel="noopener">skriva</a> inte bara designa och koda. Innehåll är svårt och viktigt, ytan kan komma sen. Ytan är ändå ett evigt work in progress som jag aldrig riktigt blir nöjd med. Att ifrågasätta sin egen process, sitt driv och reflektera över det, det känns viktigt och leder mig tillbaka till varför jag skriver det här.<br>
Det finns något väldigt lärorikt i att skriva och reflektera och det vill jag utnyttja. Sedan om någon faktiskt läser det här eller inte, det är inte lika relevant. Om du nu kommit hit, så bra jobbat! 🙂</p>
<p>Den här webbplatsen kommer främst att vara dokumentation relaterat till kodning. Min tanke är att skriva om allt det som händer när jag kodar. Det kan vara problem, lösningar, frustrationer, undersökningar, tester och annat. Förhoppningsvis så kan jag skriva om mina lösningar, men kanske inte alltid.<br>
Förutom det så kommer det nog dyka upp en del länkar, tankar om saker jag kodat. Allt kryddat med pedagogiska spörsmål.</p>
]]></content>
    </entry>
    
    
    <entry>
        <title>Learn css</title>
        <link href="https://jensa.dev/sv/posts/learn-css/"/>
        <updated>Tue, 15 Jun 2021 00:00:00 GMT</updated>
        <id>https://jensa.dev/sv/posts/learn-css/</id>
        <content type="html"><![CDATA[<p>I arbetet med att skapa den här sidan så har jag läst en del texter av <a href="https://piccalil.li/" target="_blank" rel="noopener">Andy Bells</a>. Andy är riktigt duktig och har också skapat <a href="https://github.com/andy-piccalilli/hylia" target="_blank" rel="noopener">Hylia starter kit</a> för <a href="https://www.11ty.dev/" target="_blank" rel="noopener">Eleventy</a> vilket har tjänat som grund för delar av den här sidan.<br>
Andy delar även med sig av massor med bra och intressanta artiklar. Bland detta så dök kursen <a href="https://web.dev/learn/css/" target="_blank" rel="noopener">Learn CSS</a> upp.</p>
<p>Jag har inte hunnit läsa den ännu, men skulle tro att den innehåller mycket bra. Så för min del är detta en påminnelse och för din ett tips.</p>
]]></content>
    </entry>
    
</feed>
