<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="https://www.w3.org/2005/Atom">
  <channel>
    <title>Dominic Sayers</title>
    <description>That was inedible muck, and there wasn&apos;t enough of it</description>
    <link>https://www.dominicsayers.com/</link>
    <atom:link href="https://www.dominicsayers.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Mon, 30 Mar 2026 07:39:50 +0000</pubDate>
    <lastBuildDate>Mon, 30 Mar 2026 07:39:50 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Pentest jobsworths</title>
        <description>&lt;p&gt;One of our apps has been pentested by our client’s infosec provider and the results are … less than useful.&lt;/p&gt;

&lt;p&gt;The so-called pentest appears to have been a scripted &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nmap&lt;/code&gt; (of CloudFront!) and a scripted poke around the HTTP
headers returned by the CloudFront server fronting the React app. I hope the client didn’t pay very much for a check I
could have run in 5 minutes for them.&lt;/p&gt;

&lt;p&gt;Anyway, one of the findings is that you can see from the HTTP header “Server” that the service is delivered by
CloudFront and that’s apparently a problem. Because an attacker could target their attacks based on known CloudFront
vulnerabilities, I guess.&lt;/p&gt;

&lt;p&gt;This is bullshit because there are many other ways to detect a CloudFront service and changing the Server header
achieves absolutely nothing. Except one thing: “look we’re doing something about security”. The client is a
corporate and there are literally teams of people being paid salaries to generate, manage and document this bullshit.&lt;/p&gt;

&lt;p&gt;In the meantime there is genuine, well-known and actionable technical debt that we could be addressing except for the
maintenance budget being used up by this box-checking crap.&lt;/p&gt;

&lt;p&gt;Here’s my response to the ticket. I don’t use the word “futile” very often in Jira.&lt;/p&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;I believe this finding is about the HTTP header “Server”, which in the case of our app returns&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Server: CloudFront
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Although the finding mentions port 80 (HTTP) this is also true for port 443 (HTTPS) requests.&lt;/p&gt;

&lt;p&gt;This Server header is returned whichever URL is used for either of the apps in production.&lt;/p&gt;

&lt;h3 id=&quot;options&quot;&gt;Options&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The Server header cannot be removed entirely with CloudFront.&lt;/li&gt;
  &lt;li&gt;The Server header could be set to an arbitrary string such as “Undisclosed”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;other-remarks&quot;&gt;Other remarks&lt;/h3&gt;

&lt;p&gt;CloudFront sets several other headers which identify the service’s origins as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Cache&lt;/code&gt;: this header is set to indicate whether the page was served from CloudFront’s cache and always includes the
word “CloudFront”. It cannot be user-configured and is always present.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Via&lt;/code&gt;: this header is set to indicate which of CloudFront’s CDN servers actually served the page. It always includes
the word “CloudFront” and cannot be user-configured&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Amz-Cf-Id&lt;/code&gt; , &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Amz-Cf-Pop&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Amz-Server-Side-Encryption&lt;/code&gt;: the names of these headers indicate an Amazon AWS
source for the page. They are not configurable.&lt;/li&gt;
  &lt;li&gt;The IP addresses of CloudFront’s global PoPs are well known and would reliably indicate the page has been served by
CloudFront in the absence of &lt;em&gt;any&lt;/em&gt; headers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reasoning behind this finding is that allowing an attacker to know which type of server serves the web page could
steer them towards known vulnerabilities in that engine. In the case of CloudFront it is not possible to conceal the
type of server since headers other than “Server” also identify the page’s origin.&lt;/p&gt;

&lt;p&gt;It is therefore futile to change the “Server” header to an arbitrary string as there are other ways to determine that
the page is served by CloudFront.&lt;/p&gt;

&lt;p&gt;We rely on AWS CloudFront to securely serve the React app and this is true whether or not it is identifiable as the
origin. CloudFront does not serve the app’s data which comes entirely from the back end service.&lt;/p&gt;

&lt;p&gt;If it helps you in any way to change the Server header to an arbitrary string then we can do this but all non-default
configuration options carry with them the minor risk that they are less well understood and less widely tested than
default configuration options.&lt;/p&gt;
</description>
        <pubDate>Wed, 19 Jun 2024 08:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/pentest-bullshit/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/pentest-bullshit/</guid>
        
        <category>featured</category>
        
        
      </item>
    
      <item>
        <title>No-fuss wholemeal sourdough</title>
        <description>&lt;!--excerpt.start--&gt;
&lt;p&gt;A wholemeal loaf with the minimum of process and no manual kneading
&lt;!--excerpt.end--&gt;&lt;/p&gt;

&lt;p&gt;Like everyone else I started baking with sourdough in lockdown. I stopped when my starter died while we were on holiday
in Crete. It didn’t come with us, I just left it out in a hot summer kitchen for two weeks and it asphyxiated like a dog
in a hot car. Now I keep a batch of
sourdough starter frozen in the oven in case of similar mishaps. I’ve never tried it but my mum reckons it will spring
to life when defrosted, as if nothing had happened.&lt;/p&gt;

&lt;p&gt;This is one of those recipes that seems more complicated when you write it down than it is when you do it. Especially if
you do it regularly, when it becomes second nature. If it doesn’t work first time there’s a reason for it, so just try
something slightly different next time.&lt;/p&gt;

&lt;p&gt;The fermenting of the dough and the initial creation of the levain take a long and unpredictable time. The worst case
scenario is that it’s ready for the next step at 4 o’clock in the morning and you’re sound asleep. By the time you wake
up it’s over-proved and useless. Don’t panic. You can stop the clock by putting it in the fridge. In the morning just
take it out and leave it to come up to room temperature, then the fermentation will start again.&lt;/p&gt;

&lt;p&gt;The loaf in this recipe isn’t my best work. I’m sharing it in a spirit of have-a-go and don’t worry too much about the
result. Sourdough bread always tastes great even if it hasn’t quite worked. This loaf disappeared very quickly.&lt;/p&gt;
</description>
        <pubDate>Sun, 11 Feb 2024 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/wholemeal-sourdough/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/wholemeal-sourdough/</guid>
        
        <category>featured</category>
        
        <category>recipe</category>
        
        
        <category>Breadmaking</category>
        
      </item>
    
      <item>
        <title>Slow-cooked glazed pork belly Korean style</title>
        <description>&lt;!--excerpt.start--&gt;
&lt;p&gt;A rich dish of twice-cooked pork belly in a spicy sauce.
&lt;!--excerpt.end--&gt;&lt;/p&gt;

&lt;p&gt;I served this at my 60th birthday party dinner and it all got eaten. Maybe I didn’t cook enough, or maybe it was so delicious people couldn’t bear to leave any. Who knows.&lt;/p&gt;

&lt;p&gt;The point about it is that the pork belly is cooked twice. Once in a slow cooker to render the fat and make it tender enough to fall apart. Then it is glazed and roasted to add yet more flavour.&lt;/p&gt;

&lt;p&gt;There are a lot of ingredients; most of them are optional. This is just a record of how I did it on one occasion. You do you.&lt;/p&gt;
</description>
        <pubDate>Tue, 30 Jan 2024 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/slow-cooked-belly-pork/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/slow-cooked-belly-pork/</guid>
        
        <category>featured</category>
        
        <category>recipe</category>
        
        
        <category>Slow cooker</category>
        
      </item>
    
      <item>
        <title>Nursery Spaghetti Bolognese</title>
        <description>&lt;!--excerpt.start--&gt;
&lt;p&gt;This is how I make spag bol for my kids, who are slightly fussy eaters
&lt;!--excerpt.end--&gt;&lt;/p&gt;

&lt;p&gt;This works without the meat as a pasta sauce or as pizza topping.&lt;/p&gt;

&lt;p&gt;My sister’s children eat healthy Mediterranean food with relish. My own children refused to eat anything with visible ingredients. The worst thing you can give them is food that “pops” in your mouth like peas, beans or onion pieces.&lt;/p&gt;

&lt;p&gt;So in order to get them to eat a spag bol it was necessary to remove any visible obstacles. Hence my “nursery” spag bol, which is a delicious full-flavoured sauce with no hurdles to tea-time consumption.&lt;/p&gt;
</description>
        <pubDate>Sun, 28 Jan 2024 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/nursery-spag-bol/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/nursery-spag-bol/</guid>
        
        <category>featured</category>
        
        <category>recipe</category>
        
        
        <category>Mediterranean</category>
        
      </item>
    
      <item>
        <title>Choosing an open source component</title>
        <description>&lt;p&gt;Before I approve the use of an open source component in one of my projects, there are some simple checks I ask the team to do before we use it. Below are the checks we do - you may have others, in which case I’d love to hear about them. Hit me up in the comments or on social media.&lt;/p&gt;

&lt;p&gt;I’m writing this in the week that the &lt;a href=&quot;https://twitter.com/marak/status/1479200803948830724?s=20&quot;&gt;maintainer&lt;/a&gt; of two widely-used Node packages deliberately &lt;a href=&quot;https://github.com/Marak/colors.js/commit/074a0f8ed0c31c35d13d28632bd8a049ff136fb6&quot;&gt;sabotaged his own code&lt;/a&gt; to make some kind of point, causing problems for many other projects.&lt;/p&gt;

&lt;p&gt;It’s a living example of the fragility expressed in this famous &lt;a href=&quot;https://xkcd.com/2347/&quot;&gt;XKCD cartoon&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://imgs.xkcd.com/comics/dependency.png&quot; alt=&quot;Dependency&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;license&quot;&gt;License&lt;/h2&gt;

&lt;p&gt;Open source licensing is often straightforward but can occasionally get a bit complicated and you need to assure yourself that the license under which the component is published is compatible with how you intend to use it.&lt;/p&gt;

&lt;p&gt;If you’re making some commercial software and incorporating open source components in it then this should be part of your due diligence before you sell your software or a service based on it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Most&lt;/em&gt; open source software is compatible with a commercial project although you may have to credit the authors and make a copyright declaration in your code and in your app. I won’t discuss individual licenses here and any further details are beyond the scope of this piece.&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;

&lt;p&gt;Any manifest security issues are a red flag - you should not use a component if it has security issues.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Unresolved vulnerabilities&lt;/strong&gt;: check for &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=nokogiri&quot;&gt;outstanding CVE records&lt;/a&gt;. It’s OK for a component to have had vulnerabilities in previous versions but not in the current version, especially if the vulnerability has been known about for a long time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;project-health&quot;&gt;Project health&lt;/h2&gt;

&lt;p&gt;Open source software is safe and secure so long as there are many eyes reviewing the code and a body of contributors who actively address issues. This can be assessed by reviewing the project’s source code home page, often on GitHub or GitLab.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Unmerged PRs&lt;/strong&gt;: lots of unmerged changes submitted by potential contributors is a sign that the project is not really active from the maintainer’s point of view&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Open issues&lt;/strong&gt;: lots of unanswered questions and issues is a sign that the maintainers are not giving the project as much attention as it needs&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Recent commits&lt;/strong&gt;: a lack of recent commits may mean the project is end-of-life.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Number of contributors&lt;/strong&gt;: a one-person project has two problems, a lack of eyes on the code to spot vulnerabilities and a single point of failure for the project’s lifecycle. If the central person abandons the project it dies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;contributor-background&quot;&gt;Contributor background&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Basic profiling&lt;/strong&gt;: More of a feeling than a rule, but for instance a sudden influx of contributors from one country may be a sign of inappropriate activity. On the other hand it might just reflect a new trend in that country’s engineering community. But beware.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;project-gatekeepers&quot;&gt;Project gatekeepers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Recent change of maintainer&lt;/strong&gt;: there have been examples of respectable projects turning into malware when a maintainer hands over the reins to somebody else. Something to check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;users&quot;&gt;Users&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Public sector users&lt;/strong&gt;: if this open source project is used by public sector bodies they may have done some due diligence of their own. On the other hand they may not.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Major corporate users&lt;/strong&gt;: it’s dangerous to assume that major corporates would always do due diligence before using an open source component, but it’s reassuring nonetheless to see a component in widespread corporate use.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Domicile of significant users&lt;/strong&gt;: if a piece of open source software is used exclusively or for the most part by people or organizations from a country where you would not wish to do business, that may be a warning sign.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 11 Jan 2022 08:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/choosing-an-open-source-component/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/choosing-an-open-source-component/</guid>
        
        <category>featured</category>
        
        
      </item>
    
      <item>
        <title>Code reviews commit-by-commit</title>
        <description>&lt;p&gt;Here’s how I approach a code review for a merge request (or pull request if you’re using GitHub). It’s a general approach, not language-specific. I’d really like to improve my process so if you have any thoughts or tips please let me know.&lt;/p&gt;

&lt;p&gt;This is a rough draft and needs tightening up and refactoring. I hope it makes some sort of sense as it is.&lt;/p&gt;

&lt;h2 id=&quot;bibliography&quot;&gt;Bibliography&lt;/h2&gt;

&lt;p&gt;On reviewing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/thoughtbot/guides/tree/main/code-review&quot;&gt;Guidelines on code review&lt;/a&gt; - Thoughtbot&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PJjmw9TRB7s&quot;&gt;Derek Prior video&lt;/a&gt; - worth 30 mins of your time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re looking for merge requests that use git sensibly to present a change in a way that helps us understand it. I’ve found these articles helpful to know what good looks like in this respect:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.mocoso.co.uk/talks/2015/01/12/telling-stories-through-your-commits/&quot;&gt;Telling stories through your commits&lt;/a&gt; - Joel Chippindale&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html&quot;&gt;A Note About Git Commit Messages&lt;/a&gt; - Tim Pope&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dhwthompson.com/2019/my-favourite-git-commit&quot;&gt;My favourite Git commit&lt;/a&gt; - Dave Thompson&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tekin.co.uk/2019/02/a-talk-about-revision-histories&quot;&gt;A Branch in Time (a story about revision histories)&lt;/a&gt; - Tekin Suleyman&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;not-included&quot;&gt;Not included&lt;/h2&gt;

&lt;p&gt;I’m assuming the build process includes&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;automated checks for code quality&lt;/li&gt;
  &lt;li&gt;running the test suite&lt;/li&gt;
  &lt;li&gt;checking for known security issues like vulnerabilities in 3rd party components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If not then you should put these in place. It’s not a good use of human time to do these things manually.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting started&lt;/h2&gt;

&lt;h3 id=&quot;1-read-the-merge-request-overview&quot;&gt;1. Read the merge request overview&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Do you understand the overall change that is being made, and the approach taken?&lt;/li&gt;
  &lt;li&gt;Why was the change necessary?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-review-each-commit-individually-see-below-for-how-i-do-this&quot;&gt;2. Review each commit individually (see below for how I do this)&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Click the Commits tab, then ⌘-click each commit description.&lt;/li&gt;
  &lt;li&gt;This will open a new browser tab for each commit (which I find useful).&lt;/li&gt;
  &lt;li&gt;Review the commit in isolation.&lt;/li&gt;
  &lt;li&gt;If you’re 💯 sure the commit is fine, close the tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-go-back-and-re-review-any-commits-you-didnt-fully-understand-on-the-first-pass&quot;&gt;4. Go back and re-review any commits you didn’t fully understand on the first pass&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Maybe now you’ve been through the whole code change they might make more sense.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;5-add-any-final-comments-and-questions-on-the-code&quot;&gt;5. Add any final comments and questions on the code&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Click &lt;em&gt;Submit review&lt;/em&gt; in any of the open tabs and add your summary thoughts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;reviewing-a-commit&quot;&gt;Reviewing a commit&lt;/h2&gt;

&lt;h3 id=&quot;1-read-the-commit-message&quot;&gt;1. Read the commit message&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Do you understand the change that is being made?&lt;/li&gt;
  &lt;li&gt;Do you understand the reason for the change and the approach taken?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-ask-yourself-these-questions&quot;&gt;2. Ask yourself these questions&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Has the submitter taken steps to make the review process easy for you?&lt;/li&gt;
  &lt;li&gt;Is the commit the embodiment of a single intention?&lt;/li&gt;
  &lt;li&gt;Is it comprised of the minimum code change necessary to implement that intention?&lt;/li&gt;
  &lt;li&gt;If the submitter is making you work harder than you need to then say so. Cognitive overhead is a big drain on team time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-are-there-any-code-changes-in-the-commit-that-are-not-necessary-for-what-is-described-in-the-commit-message&quot;&gt;3. Are there any code changes in the commit that are not necessary for what is described in the commit message?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Maybe they should be in a separate commit (e.g. whitespace changes, code reformatting, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-would-the-specs-pass-after-this-commit&quot;&gt;4. Would the specs pass after this commit?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;This is not a hard-and-fast rule, but ideally each commit would take a step forward without breaking any specs.&lt;/li&gt;
  &lt;li&gt;Any necessary spec changes should be in that same commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;5-if-you-dont-fully-understand-the-change-then-its-useful-to-ask-a-question-in-the-merge-request&quot;&gt;5. If you don’t fully understand the change then it’s useful to ask a question in the merge request&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Others will certainly have the same question so ask it where everybody can see it.&lt;/li&gt;
  &lt;li&gt;If you think it’s a naïve question that’s OK - stupid questions should be encouraged in your team. If they aren’t then you’re working in a poisonous environment and you should get out!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;6-answers-to-questions-should-go-in-a-commit-message&quot;&gt;6. Answers to questions should go in a commit message&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The submitter will be tempted to answer your question in the merge request web page because that’s easier&lt;/li&gt;
  &lt;li&gt;Make sure any useful information is added to the commit message then it’s in the git log for posterity.&lt;/li&gt;
  &lt;li&gt;The merge request is ephemeral, the git log is permanent.&lt;/li&gt;
  &lt;li&gt;Others in the future will undoubtedly have the same question.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;7-for-legacy-codebases-consider-this&quot;&gt;7. For legacy codebases, consider this&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;You may have a list of known exceptions to the static code quality checks because the legacy code is rubbish&lt;/li&gt;
  &lt;li&gt;For example, in Ruby using Rubocop this would be in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.rubocop_todo.yml&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Check that none of these exceptions have been fixed by this merge request, otherwise your legacy list will get out of date and be utterly useless.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;8-credit-where-its-due&quot;&gt;8. Credit where it’s due&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;If you see something doubleplusgood, say so.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;should-i-approve-the-merge-request&quot;&gt;Should I approve the merge request?&lt;/h2&gt;

&lt;p&gt;Yes, unless there is a reason not to.&lt;/p&gt;
</description>
        <pubDate>Tue, 26 Oct 2021 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/commit-by-commit-reviewing/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/commit-by-commit-reviewing/</guid>
        
        <category>featured</category>
        
        
      </item>
    
      <item>
        <title>A no-effort white loaf using a Kenwood Chef</title>
        <description>&lt;!--excerpt.start--&gt;
&lt;p&gt;This is how I make an easy and quick white loaf using my kitchen mixer. It’s trouble-free and reliable and a great time-saver.
&lt;!--excerpt.end--&gt;&lt;/p&gt;

&lt;p&gt;I mentioned my Kenwood Chef by name because I know it works. Your mixer may be just as good so long as it has a dough hook.&lt;/p&gt;

&lt;p&gt;There are longish gaps in this recipe while we wait for things to happen, like the yeast activating or the dough rising. You will find yourself with a spare egg yolk if you use the egg white I suggest in the ingredients. I now whip up a bowl of fresh mayonnaise with the egg yolk while I’m waiting for the next step in this recipe. I would never have learned how to make my own fresh mayonnaise had I not started baking bread with this recipe. By far the hardest work with this bread recipe is whisking the mayonnaise while you wait.&lt;/p&gt;

&lt;p&gt;Here are the detailed steps. I’ve made each one easy and unambiguous, I hope.&lt;/p&gt;
</description>
        <pubDate>Wed, 27 May 2020 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/white-loaf-kenwood-chef/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/white-loaf-kenwood-chef/</guid>
        
        <category>featured</category>
        
        <category>recipe</category>
        
        
        <category>Breadmaking</category>
        
      </item>
    
      <item>
        <title>The future is bleak</title>
        <description>&lt;p&gt;Sorry if this is obvious or trite but the problem isn’t Trump or Jacob Rees-Mogg, it’s that they are massively popular.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://res.cloudinary.com/dominicsayers/image/upload/e_tilt_shift:32/v1529583952/blog/2018-06-21-the-future-is-bleak/An-English-Defence-League-012.jpg&quot; alt=&quot;Someone whose identity is important to them&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Slightly more than half the people in the world seem to think that identity is the most important thing to them.&lt;/p&gt;

&lt;p&gt;Being part of a tribe and seeing that tribe victorious over its enemies is more important than overall prosperity.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dominicsayers/image/upload/v1529585303/blog/2018-06-21-the-future-is-bleak/ICF.jpg&quot; alt=&quot;The Inter-City Firm&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is the behaviour common to the Inter-City Firm in the 1980s, the Burundi Civil War in the 1990s, the Tea Party in the 2000s, UKIP, Gamergate and balkanisation in general.&lt;/p&gt;

&lt;p&gt;Two generations or more of liberal education in the UK and the US have not produced an electorate rational enough to prevent Trump or Brexit. Identity politics is majority politics.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dominicsayers/image/upload/v1529583938/blog/2018-06-21-the-future-is-bleak/faraga.jpg&quot; alt=&quot;The failed leader of a minority party in a fanboy hat&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Two things have helped reinvigorate it after decades of being a minority passtime:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The time that has elapsed since the failure of Western fascism in 1945 has removed it as a visceral shame. It’s just history now. The people who remember it are mostly dead.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dominicsayers/image/upload/v1529583952/blog/2018-06-21-the-future-is-bleak/1579859.jpg&quot; alt=&quot;Someone who remembers the previous outbreak of fascism&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Climate change and disastrous Western intervention in north African states, the Middle East and, earlier, in Central and South America has led to massive population movements. Millions of people are fleeing death and poverty and arriving at the borders of the West.&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;/assets/article_images/the-future-is-bleak/Darfur_refugee_camp_in_Chad.jpg&quot; alt=&quot;Fleeing from climate change and conflict&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m not aware of any society in history that has prevented mass migration. Borders are large, migrants are many and the cost of turning an entire country into a fortress has always been unsustainable.&lt;/p&gt;

&lt;p&gt;So it’s an easy sell. Strangers are at our gates and they are scary. The thought speaks to our irrational mind and triggers atavistic fears.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dominicsayers/image/upload/v1529583952/blog/2018-06-21-the-future-is-bleak/gate_barbarian.jpg&quot; alt=&quot;Strangers at the gates&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A compelling simple message will always win against a complex one, and if you aren’t bothered about the truth then you can make your message really compelling.&lt;/p&gt;

&lt;p&gt;Fascism was suppressed in the West after the Second World War for a few decades but in Soviet Russia, the Far East and South America authoritarian regimes drew their support from somewhere. Those regimes were (and in some cases still are) well-supported by their people.&lt;/p&gt;

&lt;p&gt;Today’s best case scenario is that Democrats get working majorities in November, and that Brexit is mitigated a bit. That’s the best case. It still leaves the far-right in power in Hungary, Poland, Italy and Turkey and fascists on the march in Germany and France.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/dominicsayers/image/upload/v1529585585/blog/2018-06-21-the-future-is-bleak/charlie-brown.jpg&quot; alt=&quot;A liberal education in progress&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Liberal education has failed to produce a rational population.&lt;/li&gt;
  &lt;li&gt;The migrants won’t go away in our generation.&lt;/li&gt;
  &lt;li&gt;A majority of people can be made to believe their identity is under threat, and that is the most important thing to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a bleak outlook.&lt;/p&gt;

&lt;p&gt;I’m not sure what can be done but signing petitions isn’t it.&lt;/p&gt;

&lt;p&gt;Education and rational suasion isn’t it; the simpler lie will win. Truth is powerless.&lt;/p&gt;

&lt;p&gt;It needs to be direct action of some sort, on a massive scale. Fascism has to be tainted with losing, like it was in 1945.&lt;/p&gt;

&lt;p&gt;That will only suppress it for a while; our children will have to do it all over again. But this time it’s our turn. Suit up.&lt;/p&gt;
</description>
        <pubDate>Thu, 21 Jun 2018 12:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/the-future-is-bleak/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/the-future-is-bleak/</guid>
        
        <category>featured</category>
        
        
      </item>
    
      <item>
        <title>Chocolate Mousse</title>
        <description>&lt;p&gt;This recipe is from our friends the Poggios. We first ate it at their house and when they came to dinner we insisted they brought chocolate mousse with them.&lt;/p&gt;

&lt;p&gt;It is extremely chocolately.&lt;/p&gt;
</description>
        <pubDate>Tue, 16 May 2017 07:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/chocolate_mousse/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/chocolate_mousse/</guid>
        
        <category>featured</category>
        
        <category>recipe</category>
        
        
        <category>Dessert</category>
        
      </item>
    
      <item>
        <title>Using Jekyll to markup a recipe</title>
        <description>&lt;p&gt;I wanted to share my no-weighing flapjack recipe with the world so I added &lt;a href=&quot;/flapjack/&quot;&gt;a post&lt;/a&gt; last month.&lt;/p&gt;

&lt;p&gt;Before I published it I researched how to mark up the HTML so that Google knew it was a recipe rather than just a bit of text. Turns out there’s a reasonably mature &lt;a href=&quot;http://schema.org/Recipe&quot;&gt;markup schema&lt;/a&gt; that &lt;a href=&quot;https://developers.google.com/search/docs/data-types/recipes&quot;&gt;Google uses&lt;/a&gt; to show recipes differently in its search results.&lt;/p&gt;

&lt;p&gt;Here’s how my recipe looks on Google:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/article_images/recipe_markup/recipe.png&quot; alt=&quot;Flapjack recipe&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, Google shows the preparation time as well as the calorific content and the star rating. This is because the post I created has the proper markup for a recipe.&lt;/p&gt;

&lt;p&gt;I wanted to be able to do this easily for any &lt;a href=&quot;/chocolate_mousse/&quot;&gt;other recipes&lt;/a&gt; I posted in the future, so I created a template that ensures that all the recipe elements are marked up correctly.&lt;/p&gt;

&lt;p&gt;To add a recipe using this template, the recipe elements (ingredients and method for example) need to be added to the page as &lt;a href=&quot;https://jekyllrb.com/docs/frontmatter/&quot;&gt;Front Matter&lt;/a&gt; (YAML) rather than just text.&lt;/p&gt;

&lt;p&gt;I tried to make this easy and human-readable. Here’s the flapjack recipe as data:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-YAML&quot;&gt;---
ingredients:
  porridge oats: 1kg
  condensed milk: 400g
  soft brown sugar: 500g
  butter: 500g
instructions:
  - Preheat the oven to 150C fan.
  - Line a large baking tin with baking parchment (my tin measures 39cm x 26cm).
  - Melt the butter and sugar in a large pan over a low heat. Don&apos;t cook the butter, just warm it enough to melt it.
  - Remove the pan from the heat and stir in the condensed milk.
  - Mix in the oats until well coated by the mixture.
  - Pour into the baking tin and smooth out with the back of a large spoon.
  - Cook for about 15-20 minutes. When the flapjack starts to brown around the edges of the tin, take it out of the oven - it should still be relatively pale in the middle.
  - Leave to cool for a few minutes before cutting into pieces.
calories: 10547
prepmins: 20
cookmins: 15
layout: recipe
title: Moist flapjack with condensed milk
date: 2017-04-21 08:00:00 +0100
image: flapjack.jpg
thumbnail: flapjack.jpg
tags:
  - featured
  - recipe
---
This recipe makes enough flapjack for two hungry children for several weeks of school lunches.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To translate this front matter into HTML I created &lt;a href=&quot;https://github.com/dominicsayers/dominicsayers.github.com/blob/master/_includes/recipe_content.html&quot;&gt;a simple layout&lt;/a&gt;. You should be able to adapt this for your own recipes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-liquid&quot; data-lang=&quot;liquid&quot;&gt;&amp;lt;!-- recipe post-content --&amp;gt;
&amp;lt;div class=&quot;post-content&quot;&amp;gt;
  &amp;lt;div class=&quot;post-reading&quot;&amp;gt;
    &amp;lt;span class=&quot;post-reading-time&quot;&amp;gt;&amp;lt;/span&amp;gt; read
  &amp;lt;/div&amp;gt;

  &amp;lt;!-- ingredients --&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;h3&amp;gt;Ingredients&amp;lt;/h3&amp;gt;
     &amp;lt;ul&amp;gt;
        &lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ingredient&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page.ingredients&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
        &amp;lt;li itemprop=&quot;ingredients&quot;&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ingredient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ingredient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
        &lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
     &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;!-- ingredients --&amp;gt;

  &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;

  &amp;lt;!-- instructions --&amp;gt;
  &amp;lt;div itemprop=&quot;recipeInstructions&quot;&amp;gt;
    &amp;lt;h3&amp;gt;Instructions&amp;lt;/h3&amp;gt;
    &amp;lt;ol&amp;gt;
      &amp;lt;li&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;instructions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
    &amp;lt;/ol&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;!-- instructions --&amp;gt;
&amp;lt;/div&amp;gt;

&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prepmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cookmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
  &amp;lt;dl class=&quot;dl-horizontal&quot;&amp;gt;
    &lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prepmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&amp;lt;dt&amp;gt;Preparation time&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prepmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt; mins&amp;lt;span itemprop=&quot;prepTime&quot; class=&quot;invisible&quot;&amp;gt;PT&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;prepmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;M&amp;lt;/span&amp;gt;&amp;lt;/dd&amp;gt;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cookmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&amp;lt;dt&amp;gt;Cooking time&amp;lt;/dt&amp;gt;&amp;lt;dd&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cookmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt; mins&amp;lt;span itemprop=&quot;cookTime&quot; class=&quot;invisible&quot;&amp;gt;PT&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cookmins&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;M&amp;lt;/span&amp;gt;&amp;lt;/dd&amp;gt;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
  &amp;lt;/dl&amp;gt;
&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;

&amp;lt;p class=&quot;invisible&quot; itemprop=&quot;description&quot;&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;excerpt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip_html&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip_newlines&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;truncate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&amp;lt;/p&amp;gt;
&amp;lt;p class=&quot;invisible&quot; itemprop=&quot;nutrition&quot; itemscope itemtype=&quot;http://schema.org/NutritionInformation&quot;&amp;gt;&amp;lt;span itemprop=&quot;calories&quot;&amp;gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;calories&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p class=&quot;invisible&quot; itemprop=&quot;aggregateRating&quot; itemscope itemtype=&quot;http://schema.org/AggregateRating&quot;&amp;gt;&amp;lt;span itemprop=&quot;ratingValue&quot;&amp;gt;5&amp;lt;/span&amp;gt;&amp;lt;span itemprop=&quot;reviewCount&quot;&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;!-- recipe post-content --&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Boom! Now I can add recipes easily and quickly.&lt;/p&gt;
</description>
        <pubDate>Mon, 15 May 2017 16:00:00 +0000</pubDate>
        <link>https://www.dominicsayers.com/recipe_markup/</link>
        <guid isPermaLink="true">https://www.dominicsayers.com/recipe_markup/</guid>
        
        <category>featured</category>
        
        
      </item>
    
  </channel>
</rss>
