<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xml" href="/static/feed.xslt"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Oli Warner&#39;s blog</title>
  <subtitle>Latest Ubuntu-flavoured posts from Oli Warner</subtitle>
  <link href="https://thepcspy.com/feeds/ubuntu.xml" rel="self"/>
  <link href="https://thepcspy.com/"/>
  <updated>2022-07-20T00:00:00Z</updated>
  <id>https://thepcspy.com/</id>
  <author>
    <name>Oli Warner</name>
  </author>
  
  <entry>
    <title>Save £23,265 with *one weird trick!*</title>
    <link href="https://thepcspy.com/read/ten-years-23k-saved/"/>
    <updated>2022-07-20T00:00:00Z</updated>
    <id>https://thepcspy.com/read/ten-years-23k-saved/</id>
    <summary type="html">&lt;p&gt;Tobacconists hate him.&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Tobacconists hate him.&lt;/p&gt;
&lt;p&gt;It’s that time of the year. I never really know who this sort of post is &lt;em&gt;for&lt;/em&gt;. Maybe it’s for you, maybe for it’s for me one dark day in the future, but…&lt;/p&gt;
&lt;h2 id=&quot;%F0%9F%8E%89-i-stopped-smoking-ten-years-ago!&quot; tabindex=&quot;-1&quot;&gt;🎉  &lt;a href=&quot;https://thepcspy.com/read/breaking-the-habit/&quot;&gt;I stopped smoking&lt;/a&gt; &lt;em&gt;&lt;strong&gt;ten years&lt;/strong&gt;&lt;/em&gt; ago!&lt;/h2&gt;
&lt;p&gt;If somebody as flimsy-willed as me can stop smoking, &lt;em&gt;&lt;strong&gt;you can stop smoking too&lt;/strong&gt;&lt;/em&gt;. I’m not going to labour the “it kills you” thing, but it is so here’s the financial breakdown for any fellow cheapskates.&lt;/p&gt;
&lt;div class=&quot;rim&quot;&gt;
&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;  10 years =  3,652 days&lt;br /&gt;   @13/day = 47,476 cigs&lt;br /&gt;           =  2,374 packs&lt;br /&gt;&lt;br /&gt;2012 price =  £7.10 /pack&lt;br /&gt;2022 price = £12.50 /pack&lt;br /&gt;Mean price =  £9.80 /pack&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I’ve not smoked &lt;strong&gt;£23,265.20&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If I’d regularly deposited that into an investment account, a 2% return that would be £25k and 5% would be almost £30k.&lt;/p&gt;
&lt;p&gt;I’d say I feel fantastic but I &lt;em&gt;am&lt;/em&gt; also ten years older. I gained two children a dog, and everything hurts. &lt;strong&gt;But I don’t smoke&lt;/strong&gt;. I don’t feel the urge to smoke, and haven’t for years. I never have to stand outdoors on cold, wet nights to smoke. I don’t panic when I’m running out of cigarettes. And that means a lot.&lt;/p&gt;
&lt;h2 id=&quot;it%E2%80%99s-easier-to-just-not-smoke&quot; tabindex=&quot;-1&quot;&gt;It’s easier to &lt;em&gt;just not smoke&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;You might not be convinced and that’s because we’re all told &lt;em&gt;it’s really hard to stop smoking&lt;/em&gt;. All the time. Even by people who want smokers to quit, as if it’s something that takes a run-up, an intake of bravery and team-cajoling. It’s not hard; just stop smoking the bloody things.&lt;/p&gt;
&lt;p&gt;The rest is understanding your body and addiction, that smoking never made you feel better, it only made &lt;em&gt;not smoking&lt;/em&gt; feel worse. As soon as you cut that cycle, your body recalibrates. As soon as you realise that, the infinitesimal cost of quitting seems worth it.&lt;/p&gt;
&lt;p&gt;If you’re trying to quit and you’re not finding it easy, stick with it. If you need help understanding addiction, &lt;a href=&quot;https://www.amazon.co.uk/dp/0615482155&quot;&gt;Allen Carr’s Easy Way to Stop Smoking&lt;/a&gt; has an eerily convincing narrative that plods through the feelings every smoker goes through. I never finished it —I convinced myself I didn’t want to quit— but it was absolutely the basis for the voice in my head that let me quit later on.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Goodbye Internet Explorer</title>
    <link href="https://thepcspy.com/read/goodbye-internet-explorer/"/>
    <updated>2022-06-15T00:00:00Z</updated>
    <id>https://thepcspy.com/read/goodbye-internet-explorer/</id>
    <summary type="html">&lt;p&gt;But what will people download Chrome with now?&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;But what will people download Chrome with now?&lt;/p&gt;
&lt;p&gt;Raise a glass, kiss your wife, hug your children. It’s finally gone.&lt;/p&gt;
&lt;figure style=&quot;float:left; margin:0 1rem 1rem -100px; shape-outside:url(ie11.svg); shape-margin: 1rem&quot; data-type=&quot;image&quot;&gt;&lt;img src=&quot;https://thepcspy.com/read/goodbye-internet-explorer/ie11.svg&quot; alt=&quot;IE11 Logo&quot; width=&quot;300&quot; height=&quot;299&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/figure&gt;
&lt;h2 id=&quot;it%E2%80%99s-dead.&quot; tabindex=&quot;-1&quot;&gt;It’s dead.&lt;/h2&gt;
&lt;p&gt;Internet Explorer has been dying for an age. 15 years ago &lt;a href=&quot;https://thepcspy.com/read/ie6-usage-is-dropping-like-a-stone/&quot;&gt;IE6 finally bit it&lt;/a&gt;, 8 years ago I was calling for webdevs to &lt;a href=&quot;https://thepcspy.com/read/time-to-bury-ie8/&quot;&gt;hasten the death of IE8&lt;/a&gt; and today is the day that Microsoft has &lt;em&gt;finally&lt;/em&gt; &lt;s&gt;pulled regular support for&lt;/s&gt; &lt;a href=&quot;https://techcommunity.microsoft.com/t5/windows-it-pro-blog/internet-explorer-11-desktop-app-retirement-faq/&quot;&gt;&lt;em&gt;“retired”&lt;/em&gt; Internet Explorer 11&lt;/a&gt;, last of its name.&lt;/p&gt;
&lt;p&gt;Its successor, Edge, uses Chrome’s renderer. While I’m sure we’ll have a long chat about the problems of monocultures one day, this means —&lt;em&gt;for now&lt;/em&gt;— we can really focus on modern standards without having to worry about what this 9 year old renderer thinks. And I mean that at a commercial, enterprise level. Use &lt;code&gt;display: grid&lt;/code&gt; without fallback code. Use ES6 features without Babel transpiling everything. &lt;strong&gt;Go, &lt;em&gt;create something&lt;/em&gt; and expect it to just work.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here’s to never having to download the multi-gigabyte, 90 day Internet Explorer test machine images. Here’s to kicking out swathes of compat code. Here’s to being able to [fairly] rigourously test a website locally without a third party running a dozen versions of Windows.&lt;/p&gt;
&lt;p&gt;The web is more free for this. &lt;em&gt;&lt;strong&gt;Rejoice!&lt;/strong&gt;&lt;/em&gt; while it lasts.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Turning my sites up to Eleven-ty</title>
    <link href="https://thepcspy.com/read/turning-it-up-to-11ty/"/>
    <updated>2022-06-12T00:00:00Z</updated>
    <id>https://thepcspy.com/read/turning-it-up-to-11ty/</id>
    <summary type="html">&lt;p&gt;This site is now powered by a static site generator called &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt;. &lt;strong&gt;It’s awesome!&lt;/strong&gt; I’ll try to explain some of my favourite things about it and reasons you might prefer it to stalwarts in the &lt;abbr title=&quot;Static Site Generator&quot;&gt;SSG&lt;/abbr&gt; arena.&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;This site is now powered by a static site generator called &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt;. &lt;strong&gt;It’s awesome!&lt;/strong&gt; I’ll try to explain some of my favourite things about it and reasons you might prefer it to stalwarts in the &lt;abbr title=&quot;Static Site Generator&quot;&gt;SSG&lt;/abbr&gt; arena.&lt;/p&gt;
&lt;figure class=&quot;nobg&quot; style=&quot;float:left; margin:3rem 1rem 1rem -100px; shape-outside:url(up-to-11.svg); shape-margin: 1.5rem&quot; data-type=&quot;image&quot;&gt;&lt;img src=&quot;https://thepcspy.com/read/turning-it-up-to-11ty/up-to-11.svg&quot; alt=&quot;Volume knob that goes to 11&quot; style=&quot;min-width:350px&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/figure&gt;
&lt;p&gt;15 years ago, training up on Django, I built a blog. It’s what webdevs did back then. It was much faster than Wordpress but the editing always fell short and the database design got in the way more than it helped. &lt;a href=&quot;https://en.wikipedia.org/wiki/Eating_your_own_dog_food&quot;&gt;Dogfooding&lt;/a&gt; your software means &lt;strong&gt;every problem is yours&lt;/strong&gt;. I had a glossy coat but the jelly and chunks arrested my writing process.&lt;/p&gt;
&lt;h2 id=&quot;ssgs-are-perfect-for-blogs-and-brochure-websites&quot; tabindex=&quot;-1&quot;&gt;&lt;abbr title=&quot;Static Site Generators&quot;&gt;SSGs&lt;/abbr&gt; are perfect for blogs and brochure websites&lt;/h2&gt;
&lt;p&gt;Static site generators churn content through templates into a static website that you can just upload to a simple webserver. This is unlike Django or any other dynamic language, where you host &lt;em&gt;a running process&lt;/em&gt; and database on an expensive server 24/7 to generate HTML on demand. You’re just serving files, &lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;for free&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most sites don’t need fresh fresh HTML for every request. They don’t change often enough. A blog or a business’ brochure website might get updates anywhere from a couple of times a day to only once or twice a year. With a static site generator, you can make your edits and  regenerate the site.&lt;/p&gt;
&lt;p&gt;It’s also secure. There’s nothing to hack running on my domain like there might be in a Wordpress install. There’s no database to run injection attacks against. There’s no indication where the source is hosted. Cloudflare assumes much of liability &lt;em&gt;for me&lt;/em&gt; (as well as the buildchain) and if I’m worried about them, it only costs me 20 minutes messing around with DNS to move to another host.&lt;/p&gt;
&lt;p&gt;I’ve used a few &lt;abbr title=&quot;Static Site Generators&quot;&gt;SSGs&lt;/abbr&gt; professionally: &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, &lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt; and &lt;a href=&quot;https://nuxtjs.org/&quot;&gt;Nuxt&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;why-pick-11ty-over-those%3F&quot; tabindex=&quot;-1&quot;&gt;Why pick &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;11ty&lt;/a&gt; over those?&lt;/h2&gt;
&lt;figure class=&quot;rim&quot; data-type=&quot;image&quot;&gt;&lt;img src=&quot;https://thepcspy.com/read/turning-it-up-to-11ty/11ty.svg&quot; alt=&quot;11ty logo&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/figure&gt;
&lt;p&gt;Jekyll is glacial on Cloudflare’s &lt;a href=&quot;https://en.wikipedia.org/wiki/CI/CD&quot; title=&quot;Continuous Integration and Continuous Deployment&quot;&gt;CI/CD environment&lt;/a&gt;; about 3 minutes a build. Hugo is &lt;em&gt;Fast&lt;/em&gt; but can be a nightmare to work with when things go wrong. Absolutely user-error, but I’ve wasted days at a time banging my head on Hugo. Both Jekyll and Hugo being non-JS options have their own take on asset management. I’m also a Vue developer so Nuxt is great &lt;em&gt;for me&lt;/em&gt;, but force-feeding users a bundle of Vue, Nuxt and routers and whatnot, just for a blog? It’s silly. It does have top-shelf asset management though.&lt;/p&gt;
&lt;p&gt;11ty was a perfect balance between Hugo and Nuxt. I get all my favourite frontend tools (PostCSS, PurgeCSS on here) with a generator that isn’t trying to force-feed my users a massive script bundle.&lt;/p&gt;
&lt;p&gt;More, &lt;em&gt;I get to pick&lt;/em&gt; the markup language I write in. I can use Markdown, Liquid, Handlebars, Nunjucks, Moustache, and many, many more. Even plain old HTML, or a mix. I can bundle images with the blog posts (like Hugo leaf bundles). I can paint extra styles on the page if I want to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I have freedom.&lt;/strong&gt; I can do anything, on any page.&lt;/p&gt;
&lt;p&gt;It’s been 3 weeks, 2 days since my initial commit on &lt;a href=&quot;https://thepcspy.com/&quot;&gt;this site&lt;/a&gt;’s repo and since finishing the conversion I’ve written more posts than I did in the previous decade, and I’ve also converted two Jekyll sites over too. Each took about an afternoon. Perfect URL parity, nothing ostensibly different, just a [much] better toolchain.&lt;/p&gt;
&lt;p&gt;What took longest was editing and upgrading 285 blog posts, spanning back to the early Naughties.&lt;/p&gt;
&lt;h2 id=&quot;fast-enough%E2%84%A2-for-developers&quot; tabindex=&quot;-1&quot;&gt;Fast Enough™ for developers&lt;/h2&gt;
&lt;p&gt;Build performance only matters &lt;em&gt;to a point&lt;/em&gt;. On this &lt;em&gt;seven year old&lt;/em&gt; laptop, 11ty generates this whole blog, 400 pages, in well under two seconds:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Copied 403 files / Wrote 539 files in 1.46 seconds (2.7ms each, v1.0.1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s a second faster on my desktop, and on a real 23 page brochure website, it’s only 0.3s.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;11ty &lt;em&gt;is&lt;/em&gt; fast&lt;/strong&gt; but whatever I use only has to be faster than me switching to my browser. Hugo is insanely fast but so what? &lt;em&gt;Anything&lt;/em&gt; less than 2 seconds is Fast Enough™. That’s what I mean.&lt;/p&gt;
&lt;h2 id=&quot;no-added-bloat-for-visitors&quot; tabindex=&quot;-1&quot;&gt;No added bloat for visitors&lt;/h2&gt;
&lt;p&gt;Many Javascript-based &lt;abbr title=&quot;Static Site Generators&quot;&gt;SSGs&lt;/abbr&gt; bundle in client code too. Sometimes this makes sense: You might use Next and Nuxt to build component rich SPAs, but for blogging and brochure stuff, an extraneous 100KB of swarf delivers a poor user experience.&lt;/p&gt;
&lt;p&gt;This may explain why I’ve actively sought out non-JS &lt;abbr title=&quot;Static Site Generators&quot;&gt;SSGs&lt;/abbr&gt; like Jekyll and Hugo before.&lt;/p&gt;
&lt;p&gt;11ty is one of the few JS &lt;abbr title=&quot;Static Site Generators&quot;&gt;SSGs&lt;/abbr&gt; that doesn’t force script on your users. If you want “pure” HTML, that’s what you’ll get. If you’re economic with your CSS, images and fonts, it’s easy to juice the performance stats.&lt;/p&gt;
&lt;figure data-type=&quot;image&quot;&gt;&lt;img src=&quot;https://thepcspy.com/read/turning-it-up-to-11ty/pagespeed.svg&quot; alt=&quot;100% on Pagespeed&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/figure&gt;
&lt;h2 id=&quot;comes-with-batteries%E2%80%A6&quot; tabindex=&quot;-1&quot;&gt;Comes with batteries…&lt;/h2&gt;
&lt;p&gt;You don’t have to pick between Markdown and Pug, Liquid or Nunjucks. You get them all, and more. &lt;a href=&quot;https://jekyllrb.com/docs/front-matter/&quot;&gt;Frontmatter&lt;/a&gt; can be in YAML, TOML, HAML, JSON even build-time javascript. So what? &lt;em&gt;So what?!&lt;/em&gt; You wouldn’t say that if you’d ever wasted a day trying to work out what the hell a Hugo site was doing because of a typo in a template whose syntax was so thick and unwelcoming, kings built castle walls with it.&lt;/p&gt;
&lt;p&gt;11ty is simple and flexible.&lt;/p&gt;
&lt;p&gt;There’s also a &lt;em&gt;huge&lt;/em&gt; pile of &lt;a href=&quot;https://www.npmjs.com/search?q=11ty&quot;&gt;community 11ty plugins&lt;/a&gt; too.&lt;/p&gt;
&lt;h2 id=&quot;%E2%80%A6-but-you-can-use-your-own&quot; tabindex=&quot;-1&quot;&gt;… But you can use your own&lt;/h2&gt;
&lt;p&gt;If you don’t get on with something in 11ty, you use something else, or rip it; do your own thing.&lt;/p&gt;
&lt;p&gt;The Eureka moment for me was when I got into a fight with the markdown engine. I wanted to extend it to handle some of the custom things I did in my old blog posts, that I’d implemented in Django. Code to generate Youtube embeds, special floats, &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; sidebars, etc. It would have been a nightmare to upgrade every post.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;markdown-it&lt;/code&gt; and &lt;code&gt;markdown-it-container&lt;/code&gt; I completely replaced the Markdown engine with something I could hack on. Here’s a real “explainer” snippet I have and use:&lt;/p&gt;
&lt;aside&gt;&lt;details&gt;&lt;summary&gt;Open this &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; to see the 11ty code that generated it…&lt;/summary&gt;
&lt;p&gt;If I want one of these blocks, I can put this in my post:&lt;/p&gt;
&lt;pre class=&quot;language-markdown&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;:::explainer Click this to see how I configured this in 11ty&lt;br /&gt;...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is configured in the main &lt;code&gt;.eleventy.js&lt;/code&gt; config&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; md &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;markdown-it&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;md&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;markdown-it-container&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;explainer&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function-variable function&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; params&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&lt;span class=&quot;token anchor function&quot;&gt;^&lt;/span&gt;explainer&lt;span class=&quot;token char-set class-name&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token function-variable function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;tokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tokens&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;info&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&lt;span class=&quot;token anchor function&quot;&gt;^&lt;/span&gt;explainer&lt;span class=&quot;token char-set class-name&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-set class-name&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token anchor function&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tokens&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nesting &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;aside&gt;&amp;lt;details&gt;&amp;lt;summary&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;md&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderInline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;/summary&gt;\n&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&amp;lt;/details&gt;&amp;lt;/aside&gt;\n&#39;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;eleventyConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;br /&gt;  eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setLibrary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;md&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; md&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;&lt;/aside&gt;
&lt;p&gt;It’s important to stress that neither of those projects are &lt;em&gt;for&lt;/em&gt; 11ty. They’re just two of a million projects sitting on npm for anyone to use. 11ty just makes it easy to use any of this stuff on your pages.&lt;/p&gt;
&lt;p&gt;Adding template-filters for all the bundled template languages is also made really simple:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;striptags&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&amp;lt;&lt;span class=&quot;token group punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char-class&quot;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token char-class-negation operator&quot;&gt;^&lt;/span&gt;&gt;&lt;span class=&quot;token char-class-punctuation punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token quantifier number&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&gt;&lt;span class=&quot;token group punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;gi&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’ve ever used &lt;em&gt;opinionated software&lt;/em&gt; before —perhaps even your own— you’ll appreciate that 11ty isn’t just getting out of your way, &lt;strong&gt;it’s going out of its way to make your life &lt;em&gt;easy&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;what%E2%80%99s-not-so-good%3F&quot; tabindex=&quot;-1&quot;&gt;What’s not so good?&lt;/h2&gt;
&lt;p&gt;I’m three sites into 11ty now, I’ve seen how I work with it and I’ve bumped into a few things I’m not gushing about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pagination is good and frustrating in equal measure. Collections seem like a good idea, filtering them into new collections is easy enough, but actually paginating them can be a bit of a mess. To show &lt;a href=&quot;https://thepcspy.com/tag/webdev/&quot;&gt;a tag page&lt;/a&gt;, for example, &lt;a href=&quot;https://www.11ty.dev/docs/quicktips/tag-pages/&quot;&gt;you actually use pagination to filter the collection to that tag&lt;/a&gt;. But then you can’t [easily] re-paginate &lt;em&gt;that&lt;/em&gt; data, so I just show all posts from that tag rather than 15.&lt;/p&gt;
&lt;p&gt;If I had hundreds of posts in any one tag, this’d be a problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For all my complaints with Jekyll and Hugo’s wonky asset pipelines, 11ty’s is completely decoupled.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;https://www.npmjs.com/package/eleventy-plugin-postcss&quot;&gt;&lt;code&gt;eleventy-plugin-postcss&lt;/code&gt;&lt;/a&gt; to call PostCSS at roughly the right time (and update on changes) but I could just as easily handle that externally. There’s nothing in 11ty (obvious to me anyway) to ingest that back into the templates.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can’t easily inline classes that only get used on one page.&lt;/li&gt;
&lt;li&gt;You can’t easily hash the filenames and update the links that call them &lt;em&gt;&lt;strong&gt;after&lt;/strong&gt;&lt;/em&gt; generating the post HTML (that’s important with PurgeCSS).&lt;/li&gt;
&lt;li&gt;Media handling could be tighter. The &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot;&gt;Image plugin&lt;/a&gt; is official, but this should be part of the project IMO, and not rely on &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/#use-this-in-your-templates&quot;&gt;this hairy shortcode&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s important to stress that I’m using 11ty in order that I don’t &lt;em&gt;need&lt;/em&gt; bundles, but some of these complaints would be assuaged if the system could parse bundle manifests, so I could use external tools rather than just a dumb static assets and have the right filenames pulled in (at the right time).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A scoped include like Django’s would solve a couple of problems I’ve hacked around:&lt;/p&gt;
&lt;pre class=&quot;language-django&quot;&gt;&lt;code class=&quot;language-django&quot;&gt;&lt;span class=&quot;token django language-django&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;token tag keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;template&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;variable&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Saneef points out that &lt;strong&gt;this &lt;em&gt;is&lt;/em&gt; possible&lt;/strong&gt; by &lt;a href=&quot;https://www.trysmudford.com/blog/encapsulated-11ty-components/&quot;&gt;leveraging the macro functions in Nunjucks&lt;/a&gt;. It’s a bit of a mouthful. I’d prefer a first-party solution (which I guess would actually have to come as part of the Nunjucks), but again it’s interesting to see just how flexible this thing is.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Named/keyword arguments in shortcodes would also be nice, so I don’t have to provide every option to just use the last, but I guess this would require some thinking to overcome the lack of support for destructured parameters in ES6.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are small complaints, maybe already with solutions I’ve just not seen yet.&lt;/p&gt;
&lt;p&gt;I’ve still managed to transfer three sites to 11ty in a couple of weeks and I wouldn’t have done that if I didn’t think it worked well enough. &lt;strong&gt;I’m really happy with 11ty.&lt;/strong&gt; I’d heartily recommend it to anyone.&lt;/p&gt;
</content>
  </entry>
</feed>