<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Dev Notes - Articles</title>
    <description>Software Development Resources by David Egan.</description>
    <link>https://dev-notes.eu</link>
		<atom:link href="http://dev-notes.eu/feed.xml" rel="self" type="application/rss+xml" />
    
      
      <item>
        <title>Branch Management With Git Worktree</title>
        <description>&lt;p&gt;If you need to frequently switch between Git branches, the &lt;code class=&quot;highlighter-rouge&quot;&gt;worktree&lt;/code&gt; feature can be a useful way of working since it allows you to check out more than one branch at a time.&lt;/p&gt;

&lt;p&gt;It avoids the necessity of either committing or stashing changes before switching to a different branch because each branch is managed in a new working tree - i.e. worktree branches exist as a separate directory trees on your filesytem.&lt;/p&gt;

&lt;p&gt;You can add a new worktree at any path - I find it convenient to add &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees&lt;/code&gt; to a global &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; and add worktree branches to a &lt;code class=&quot;highlighter-rouge&quot;&gt;.wortrees&lt;/code&gt; subdirectory of the main project root.&lt;/p&gt;

&lt;h2 id=&quot;why-bother&quot;&gt;Why Bother?&lt;/h2&gt;
&lt;p&gt;You’re deep in refactoring on a feature branch and you need to review a co-worker’s PR for a hotfix urgently.&lt;/p&gt;

&lt;p&gt;You could add &amp;amp; commit your changes, but they are currently not in a satisfactory state and you are aiming to keep the project commit history as clean as possible. You could stash changes, change to the PR branch, and pop the stash when finished, but this is messy and can be confusing if you’re managing multiple stashes.&lt;/p&gt;

&lt;p&gt;Adding the PR as a new worktree branch allows you to simply change directory into the new PR branch without worrying about disturbing complex ongoing changes in the branch you’re working on.&lt;/p&gt;

&lt;h2 id=&quot;basic-example-add-new-branch-as-a-worktree&quot;&gt;Basic Example: Add New Branch as a Worktree&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add &amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To add a &lt;code class=&quot;highlighter-rouge&quot;&gt;hotfix&lt;/code&gt; worktree, from the project root:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add .worktrees/hotfix
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This creates a new branch named &lt;code class=&quot;highlighter-rouge&quot;&gt;hotfix&lt;/code&gt; - the final component of &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees/hotfix&lt;/code&gt; - and checks it out at the &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees/hotfix&lt;/code&gt; path.&lt;/p&gt;

&lt;p&gt;Add a second worktree branch:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add .worktrees/feature-1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The project file structure now looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.
├── README.md
└── .worktrees
    ├── feature-1
    │   └── README.md
    └── hotfix
        └── README.md

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The top level &lt;code class=&quot;highlighter-rouge&quot;&gt;README.md&lt;/code&gt; is in the original branch.&lt;/p&gt;

&lt;p&gt;At this point, running &lt;code class=&quot;highlighter-rouge&quot;&gt;git branch&lt;/code&gt; from the top level of the project shows:&lt;/p&gt;

&lt;pre&gt;  dev
+ &lt;font color=&quot;#2AA198&quot;&gt;feature-1&lt;/font&gt;
+ &lt;font color=&quot;#2AA198&quot;&gt;hotfix&lt;/font&gt;
* &lt;font color=&quot;#859900&quot;&gt;master&lt;/font&gt;
&lt;/pre&gt;

&lt;p&gt;This shows a branch &lt;code class=&quot;highlighter-rouge&quot;&gt;dev&lt;/code&gt; that is not a worktree, along with two worktree branches &lt;code class=&quot;highlighter-rouge&quot;&gt;feature-1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;hotfix&lt;/code&gt; marked with the &lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt; symbol.&lt;/p&gt;

&lt;p&gt;The current checked-out branch &lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt; is marked with a &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you move into &lt;code class=&quot;highlighter-rouge&quot;&gt;hotfix&lt;/code&gt; - &lt;code class=&quot;highlighter-rouge&quot;&gt;cd .worktrees/hotfix&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;git branch&lt;/code&gt; will now show:&lt;/p&gt;

&lt;pre&gt;  dev
+ &lt;font color=&quot;#2AA198&quot;&gt;feature-1&lt;/font&gt;
* &lt;font color=&quot;#859900&quot;&gt;hotfix&lt;/font&gt;
+ &lt;font color=&quot;#2AA198&quot;&gt;master&lt;/font&gt;
&lt;/pre&gt;

&lt;p&gt;In each case, the current branch is colorised and marked with an asterisk. The plus symbol indicates that you can access/work on the branch by moving in to the relevant directory.&lt;/p&gt;

&lt;p&gt;In the example above, the &lt;code class=&quot;highlighter-rouge&quot;&gt;dev&lt;/code&gt; branch does not have a linked worktree.&lt;/p&gt;

&lt;h2 id=&quot;work-on-existing-branch-in-a-new-worktree&quot;&gt;Work on Existing Branch in a New Worktree&lt;/h2&gt;

&lt;p&gt;To set up an existing branch as a worktree, run &lt;code class=&quot;highlighter-rouge&quot;&gt;git worktree add &amp;lt;path&amp;gt; &amp;lt;branch&amp;gt;&lt;/code&gt;. For example:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add .worktrees/my-existing-branch my-existing-branch
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A new working tree is created at &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees/my-existing-branch&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;my-existing-branch&lt;/code&gt; is checked out at this location.&lt;/p&gt;

&lt;h2 id=&quot;remove-worktrees&quot;&gt;Remove Worktrees&lt;/h2&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;git worktree remove worktree-name&lt;/code&gt; - where &lt;code class=&quot;highlighter-rouge&quot;&gt;worktree-name&lt;/code&gt; is the final component of the worktree path. If you’re unsure of the worktree name, &lt;code class=&quot;highlighter-rouge&quot;&gt;git worktree list&lt;/code&gt; will list worktrees in the current repo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree list
/tmp/tmp.e4JD71KDKU                       0f4b170 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master]
/tmp/tmp.e4JD71KDKU/.worktrees/feature-1  3471bba &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;feature-1]
/tmp/tmp.e4JD71KDKU/.worktrees/hotfix     565c127 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;hotfix]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To remove the &lt;code class=&quot;highlighter-rouge&quot;&gt;hotfix&lt;/code&gt; worktree:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree remove hotfix
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The hotfix worktree is now removed, but the branch is still available should you still need it.&lt;/p&gt;

&lt;p&gt;If you just delete the worktree directory without using &lt;code class=&quot;highlighter-rouge&quot;&gt;git worktree remove&lt;/code&gt;, don’t panic - Git has you covered. Garbage collection will eventually remove the metadata files for the (now non-existent) worktree.&lt;/p&gt;

&lt;h2 id=&quot;working-on-branches&quot;&gt;Working on Branches&lt;/h2&gt;

&lt;p&gt;To work on a worktree branch, move into the correct directory. Make changes as required and use &lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;git commit&lt;/code&gt; as usual. When you’re finished, simply return to the original directory.&lt;/p&gt;

&lt;h2 id=&quot;fetch-a-pr-github-and-set-up-as-a-worktree&quot;&gt;Fetch a PR GitHub and Set Up as a Worktree&lt;/h2&gt;
&lt;p&gt;Save this script as an executable file named &lt;code class=&quot;highlighter-rouge&quot;&gt;gitfetch-pr&lt;/code&gt; in your &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# /path/gitfetch-pr&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; -euo pipefail

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;usage &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	cat &lt;span class=&quot;sh&quot;&gt;&amp;lt;&amp;lt;- EOF
	Provide the PR reference number from within a Git project:
	$(basename $0) &amp;lt;PR reference number&amp;gt; 
	EOF
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;!&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; usage; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; -d &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PWD&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/.git&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;No .git directory detected.&quot;&lt;/span&gt;; usage; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;2; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~ ^[0-9]+&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;The PR reference should be an integer.&quot;&lt;/span&gt;; usage; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;3; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

git fetch origin &lt;span class=&quot;s2&quot;&gt;&quot;pull/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/head:PR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Done.&quot;&lt;/span&gt;

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

&lt;p&gt;You can now run &lt;code class=&quot;highlighter-rouge&quot;&gt;gitfetch-pr 42&lt;/code&gt; to fetch the commit associated with pull request #42 and set this up as a branch &lt;code class=&quot;highlighter-rouge&quot;&gt;PR42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To set this up as a worktree, run:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add .worktrees/PR42 PR42
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can view the PR42 commit by navigating to &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees/PR42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You could also set this up as a git alias rather than a shell script, as demonstrated in the following example.&lt;/p&gt;

&lt;h2 id=&quot;fetch--checkout-a-gitlab-merge-request&quot;&gt;Fetch &amp;amp; Checkout a GitLab Merge Request&lt;/h2&gt;

&lt;p&gt;This can be achieved with a &lt;code class=&quot;highlighter-rouge&quot;&gt;git alias&lt;/code&gt;. Add the following to &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.gitconfig&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;# Allows: `git mr origin 5` to fetch &amp;amp; checkout MR 5 from origin&lt;/span&gt;
	mr &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; !sh -c &lt;span class=&quot;s1&quot;&gt;'git fetch $1 merge-requests/$2/head:mr-$1-$2 &amp;amp;&amp;amp; git checkout mr-$1-$2'&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To use, run &lt;code class=&quot;highlighter-rouge&quot;&gt;git mr origin 42&lt;/code&gt; fetches the specified merge request into a local &lt;code class=&quot;highlighter-rouge&quot;&gt;mr-upstream-42&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;To use this as a worktree:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git worktree add .worktrees/mr42 mr-origin-42
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This adds the branch &lt;code class=&quot;highlighter-rouge&quot;&gt;mr-origin-42&lt;/code&gt; to the worktree directory &lt;code class=&quot;highlighter-rouge&quot;&gt;.worktrees/mr42&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;using-standard-branch-comparison&quot;&gt;Using Standard Branch Comparison&lt;/h2&gt;
&lt;p&gt;You can still compare across branches and pull specific hunks as you would usually do. For example, if working in the hotfix worktree you can view (and &lt;code class=&quot;highlighter-rouge&quot;&gt;diffput&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;diffget&lt;/code&gt;) differences between the current file in the current branch and the same file in the feature-1 branch using vim fugitive:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;:Gvdiff feature-1:%
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively, open a split window in your editor, open the same file in a different worktree and pull changes using the editor’s fucntionality.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-worktree&quot;&gt;Git Worktree Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 27 Jun 2022 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2022/06/Branch-Management-With-Git-Worktree/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2022/06/Branch-Management-With-Git-Worktree/</guid>
      </item>
      
    
      
      <item>
        <title>Cargo Add for Dependency Management</title>
        <description>&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo add [OPTIONS] &amp;lt;DEP&amp;gt;&lt;/code&gt; is a useful command that adds dependencies to a &lt;code class=&quot;highlighter-rouge&quot;&gt;Cargo.toml&lt;/code&gt; manifest file.&lt;/p&gt;

&lt;p&gt;To install:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo install cargo-edit
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;p&gt;In the root of your project run:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo add serde
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will add the dependency and update your &lt;code class=&quot;highlighter-rouge&quot;&gt;Cargo.toml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;For full instructions, run &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo add --help&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;git-setup&quot;&gt;Git Setup&lt;/h2&gt;

&lt;p&gt;If you have overridden your access to a remote git service to use SSH rather than HTTPS, you may need to tweak your &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.gitconfig&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cargo add serde                
    Updating &lt;span class=&quot;s1&quot;&gt;'https://github.com/rust-lang/crates.io-index'&lt;/span&gt; index
Error: failed to acquire username/password from &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;configuration                                                                                                                                                                                                                                                          
                                                                               
Caused by:                                    
    failed to acquire username/password from &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The solution - add this to &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.gitconfig&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# existing github.com override&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;url &lt;span class=&quot;s2&quot;&gt;&quot;git@github.com:&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
	insteadOf &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; https://github.com/

&lt;span class=&quot;c&quot;&gt;# fine-tune the override to avoid issues with cargo-edit&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;url &lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/rust-lang/crates.io-index&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
	insteadOf &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; https://github.com/rust-lang/crates.io-index
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</description>
        <pubDate>Sat, 11 Jun 2022 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2022/06/Cargo-Add-for-Dependency-Management/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2022/06/Cargo-Add-for-Dependency-Management/</guid>
      </item>
      
    
      
      <item>
        <title>Rules of Borrowing in Rust</title>
        <description>&lt;p&gt;This is a personal note/reminder on borrowing rules in Rust.&lt;/p&gt;

&lt;h2 id=&quot;rules-for-variables&quot;&gt;Rules for Variables&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Each value has a variable which is it’s owner.&lt;/li&gt;
  &lt;li&gt;There can only be one owner of a value at a time.&lt;/li&gt;
  &lt;li&gt;When the owner goes out of scope, the value is dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;rules-of-borrowing&quot;&gt;Rules of Borrowing&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Unlimited borrows for read-only borrows: &lt;code class=&quot;highlighter-rouge&quot;&gt;let a = &amp;amp;x&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;For a read only borrow, the original data is immutable for the duration of the borrow&lt;/li&gt;
  &lt;li&gt;You can only have a single borrow at a time for mutable borrows: &lt;code class=&quot;highlighter-rouge&quot;&gt;let a = &amp;amp;mut x&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/// Notes ownership and borrowing.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&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;err&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// You can't access a at this point because it has been mutably borrowed&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// from. The following line won't compile, with the error message:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// `cannot borrow `a` as immutable because it is also borrowed as mutable`:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// println!(&quot;a: {:?}&quot;, a);&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// b: [1, 2]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// b: [42, 2]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// a is accessible again:&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// a: [42, 2, 3, 4]&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</description>
        <pubDate>Fri, 15 Apr 2022 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2022/04/Rules-of-Borrowing-in-Rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2022/04/Rules-of-Borrowing-in-Rust/</guid>
      </item>
      
    
      
      <item>
        <title>Add Methods To An Existing Type in Go</title>
        <description>&lt;p&gt;Code re-use in object-oriented Go is achieved by means of composition rather than inheritance.&lt;/p&gt;

&lt;p&gt;Composition means that an object &lt;em&gt;contains&lt;/em&gt; another object (“has a …”) rather than &lt;em&gt;extending&lt;/em&gt; another object(“is a …”).&lt;/p&gt;

&lt;p&gt;Instead of overriding functions, function calls are delegated to the internal object.&lt;/p&gt;

&lt;h2 id=&quot;add-method-to-an-existing-type&quot;&gt;Add Method to An Existing Type&lt;/h2&gt;

&lt;p&gt;You can modify a type locally by type definition or embedding.&lt;/p&gt;

&lt;h3 id=&quot;type-definition&quot;&gt;Type Definition&lt;/h3&gt;
&lt;p&gt;Create an alias to the external type.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Provides direct access to fields of the external type&lt;/li&gt;
  &lt;li&gt;DOES NOT provide access to methods of the external type&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;// Parent is a type defined in package-name with a field FamilyName and a method GetFamilyName&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FamilyName&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;// OK&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetFamilyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;// Won't work unless the method is defined specifically on child&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;embedding&quot;&gt;Embedding&lt;/h3&gt;
&lt;p&gt;Embedding is a Go feature that eases type composition.&lt;/p&gt;

&lt;p&gt;If a type A is included as a nameless parameter in type B, then the methods defined on type A are accessible through type B.&lt;/p&gt;

&lt;p&gt;The compiler uses the concept of &lt;em&gt;promotion&lt;/em&gt; to export properties &amp;amp; methods of the embedded type to the embedding type.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If a type contains a field of another type, but no name is assigned to that field, it is an &lt;em&gt;embedded&lt;/em&gt; field.&lt;/p&gt;

  &lt;p&gt;Fields or methods on the embedded field are promoted to the containing struct.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If types are listed within a struct without giving them field names, they are &lt;em&gt;embedded&lt;/em&gt;. This promotes the methods of the embedded types - they are available to the containing type. The local type then:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Has access to all fields of the parent&lt;/li&gt;
  &lt;li&gt;Has access to methods of the parent - they are promoted to the local type&lt;/li&gt;
  &lt;li&gt;If the embedded type is a pointer, it must be initialised separately&lt;/li&gt;
  &lt;li&gt;You can’t embed a non-struct type within a struct and get access to the parent methods&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://golang.org/doc/effective_go.html#embedding&quot;&gt;Docs on Embedding&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/43507669/3590673&quot;&gt;Good SO Answer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 20 Jun 2021 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2021/06/Add-Methods-To-An-Existing-Type-in-Go/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2021/06/Add-Methods-To-An-Existing-Type-in-Go/</guid>
      </item>
      
    
      
      <item>
        <title>Use Delve to Run and Debug a Single Unit Test in Go</title>
        <description>&lt;p&gt;If you want to run a single unit test in the Delve debugger for Go, here’s how you do it on the command line:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dlv &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;github.com/path/to/package/testsuite -- -test.run ^Test_Random&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The command is run from within &lt;code class=&quot;highlighter-rouge&quot;&gt;path/to/package/testsuite&lt;/code&gt; - the start point for the debugger will be the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestRandom&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Once the debugger builds the test binary and launches, you can set breakpoints relative to the start of the function. For example:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;b TestRandom:5&lt;/code&gt; sets a breakpoint on the 5th line of the function.&lt;/p&gt;

&lt;p&gt;I’m fairly new to Go, and debugging from witin the go-vim plugin allows the same functionality using the &lt;code class=&quot;highlighter-rouge&quot;&gt;:GoDebugTestFunc&lt;/code&gt; command with the cursor on the required function.&lt;/p&gt;

&lt;p&gt;So far, I prefer multiplexing with Tmux, with my code in Vim in one pane and the debugger in the other.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/issues/636#issuecomment-357029683&quot;&gt;Comment on Delve Github issue #636&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 19 Apr 2021 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2021/04/Use-Delve-to-Run-and-Debug-a-Single-Unit-Test-in-Go/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2021/04/Use-Delve-to-Run-and-Debug-a-Single-Unit-Test-in-Go/</guid>
      </item>
      
    
      
      <item>
        <title>Virtualenv &amp; Virtualenvwrapper Setup in Python 3 on Ubuntu Focal Fossa</title>
        <description>&lt;p&gt;This article outlines Virtualenv and Virtualenvwrapper installation on Python 3 on Ubuntu.&lt;/p&gt;

&lt;p&gt;A virtual environment in Python is an isolated working copy of Python and associated modules that allows you to work on a specific project without fear of affecting other projects or your system as a whole.&lt;/p&gt;

&lt;h2 id=&quot;virtualenv&quot;&gt;Virtualenv&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; creates a folder which holds all the necessary modules for a project.&lt;/p&gt;

&lt;p&gt;A new virtual environment is created by:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd project_directory
virtualenv my_project
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You could also keep all virtual environments in one directory, and activate your environment by referencing this.&lt;/p&gt;

&lt;p&gt;An environment is started by sourcing a file &lt;code class=&quot;highlighter-rouge&quot;&gt;bin/activate&lt;/code&gt; located in the isolated environment. For example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;. /path_to_environments/my_project/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This changes your prompt to reflect the virtual environment - in this case: &lt;code class=&quot;highlighter-rouge&quot;&gt;(my_project)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you have used &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt; to install modules within the environment, you can easily reproduce the specific context by creating a &lt;code class=&quot;highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt; manifest file with the &lt;code class=&quot;highlighter-rouge&quot;&gt;pip freeze&lt;/code&gt; command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can add this file into version control, and use it to set up a new virtualenv as required:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Set up a new virtualenv&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Install dependencies in the requirements.txt&lt;/span&gt;
pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;install-virtualenv&quot;&gt;Install Virtualenv&lt;/h2&gt;
&lt;p&gt;Install &lt;code class=&quot;highlighter-rouge&quot;&gt;pip3&lt;/code&gt; if necessary:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install python3-pip
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Add an alias for the &lt;code class=&quot;highlighter-rouge&quot;&gt;pip3&lt;/code&gt; command. Add to &lt;code class=&quot;highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt; if you want to make this permanent:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;alias pip='pip3'
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Install Virtualenv:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;virtualenvwrapper&quot;&gt;Virtualenvwrapper&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;virtualenvwrapper&lt;/code&gt; is a set of shell functions that serve as extensions to&lt;code class=&quot;highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The extensions include wrappers for creating and deleting virtual environments and otherwise managing your development workflow, making it easier to work on more than one project at a time without introducing conflicts in their dependencies.&lt;/p&gt;

&lt;h3 id=&quot;install-virtualenvwrapper&quot;&gt;Install Virtualenvwrapper&lt;/h3&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install virtualenvwrapper
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Add the following to &lt;code class=&quot;highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;.profile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Next line not necessary unless you want to specify a different location - ~/.virtualenvs is the default&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WORKON_HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.virtualenvs

&lt;span class=&quot;c&quot;&gt;# $PROJECT_HOME tells virtualenvwrapper where to place project working directories.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This is required for the `mkproject` command.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PROJECT_HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Devel

&lt;span class=&quot;c&quot;&gt;# Source the script, making functions available in the shell&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; /usr/local/bin/virtualenvwrapper.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;virtualenvwrapper-quickstart&quot;&gt;Virtualenvwrapper Quickstart&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;workon&lt;/code&gt;: display a list of environments (which will be empty on first run)&lt;/li&gt;
  &lt;li&gt;Run: &lt;code class=&quot;highlighter-rouge&quot;&gt;mkvirtualenv temp&lt;/code&gt;: a new environment &lt;code class=&quot;highlighter-rouge&quot;&gt;temp&lt;/code&gt; is created and activated&lt;/li&gt;
  &lt;li&gt;Run: &lt;code class=&quot;highlighter-rouge&quot;&gt;workon&lt;/code&gt;: the new &lt;code class=&quot;highlighter-rouge&quot;&gt;temp&lt;/code&gt; environment is included&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;deactivate&lt;/code&gt; to return to the system installed Python&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://virtualenvwrapper.readthedocs.io/en/latest/install.html&quot;&gt;virtualenvwrapper docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 19 Jan 2021 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2021/01/Virtualenv-&amp;-Virtualenvwrapper-Setup-in-Python-3-on-Ubuntu-Focal-Fossa/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2021/01/Virtualenv-&amp;-Virtualenvwrapper-Setup-in-Python-3-on-Ubuntu-Focal-Fossa/</guid>
      </item>
      
    
      
      <item>
        <title>LUKS Encrypt Hard Drive with Cryptsetup on Ubuntu 20.04</title>
        <description>&lt;p&gt;This article outlines how to LUKS encrypt a secondary drive on Ubuntu 20.04 Focal Fossa using &lt;code class=&quot;highlighter-rouge&quot;&gt;cryptsetup&lt;/code&gt; on the command line.&lt;/p&gt;

&lt;h2 id=&quot;find-the-unmounted-disk&quot;&gt;Find the Unmounted Disk&lt;/h2&gt;

&lt;p&gt;Once you have physically connected the disk, find the unmounted disk in the system using &lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsblk

&lt;span class=&quot;c&quot;&gt;# Typical output:&lt;/span&gt;
NAME                    MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                       8:0    0 465.8G  0 disk
├─sda1                    8:1    0   512M  0 part
├─sda2                    8:2    0   488M  0 part  /boot
└─sda3                    8:3    0 464.8G  0 part
  └─sda3_crypt          252:0    0 464.8G  0 crypt
    ├─ubuntu--vg-root   252:1    0 448.8G  0 lvm   /
    └─ubuntu--vg-swap_1 252:2    0    16G  0 lvm
      └─cryptswap1      252:3    0    16G  0 crypt &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;SWAP]
sdb                       8:16   0 931.5G  0 disk
└─sdb_crypt             252:4    0 931.5G  0 crypt /media/secure-hdd-2
sdc                       8:32   0   1.8T  0 disk
├─sdc1                    8:33   0 994.9G  0 part  /media/datadrive
└─sdc2                    8:34   0 868.2G  0 part
  └─sdc2_crypt          252:5    0 868.2G  0 crypt /media/secure-hdd
sdd                       8:48   0 931.5G  0 disk
loop0                     7:0    0  83.8M  1 loop  /snap/core/3604
loop1                     7:1    0 178.2M  1 loop  /snap/atom/112
loop2                     7:2    0 174.2M  1 loop  /snap/atom/116
loop3                     7:3    0  28.1M  1 loop  /snap/telegram-latest/4
loop4                     7:4    0  83.8M  1 loop  /snap/core/3748
loop5                     7:5    0  81.3M  1 loop  /snap/core/3887
loop6                     7:6    0 178.2M  1 loop  /snap/atom/111
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In this case you can see &lt;code class=&quot;highlighter-rouge&quot;&gt;sdd&lt;/code&gt; is the target drive - the size type matches, and it is unmounted (as expected).&lt;/p&gt;

&lt;p&gt;Double check disk info:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo hdparm -i /dev/sdd

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;

/dev/sdd:

 &lt;span class=&quot;nv&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Samsung SSD 860 EVO 1TB, &lt;span class=&quot;nv&quot;&gt;FwRev&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;RVT01B6Q, &lt;span class=&quot;nv&quot;&gt;SerialNo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;S3Z9NB0JC01523A
 &lt;span class=&quot;nv&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt; Fixed &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;nv&quot;&gt;RawCHS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;16383/16/63, &lt;span class=&quot;nv&quot;&gt;TrkSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0, &lt;span class=&quot;nv&quot;&gt;SectSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0, &lt;span class=&quot;nv&quot;&gt;ECCbytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
 &lt;span class=&quot;nv&quot;&gt;BuffType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;unknown, &lt;span class=&quot;nv&quot;&gt;BuffSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;unknown, &lt;span class=&quot;nv&quot;&gt;MaxMultSect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1, &lt;span class=&quot;nv&quot;&gt;MultSect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1
 &lt;span class=&quot;nv&quot;&gt;CurCHS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;16383/16/63, &lt;span class=&quot;nv&quot;&gt;CurSects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;16514064, &lt;span class=&quot;nv&quot;&gt;LBA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;yes, &lt;span class=&quot;nv&quot;&gt;LBAsects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1953525168
 &lt;span class=&quot;nv&quot;&gt;IORDY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;on/off, &lt;span class=&quot;nv&quot;&gt;tPIO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;min:120,w/IORDY:120&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;tDMA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;min:120,rec:120&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
 PIO modes:  pio0 pio1 pio2 pio3 pio4
 DMA modes:  mdma0 mdma1 mdma2
 UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;udma6
 &lt;span class=&quot;nv&quot;&gt;AdvancedPM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;no &lt;span class=&quot;nv&quot;&gt;WriteCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;enabled
 Drive conforms to: unknown:  ATA/ATAPI-2,3,4,5,6,7

 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; signifies the current active mode
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If this checks out, you have the device reference.&lt;/p&gt;

&lt;p&gt;Alternatively, list all drives in short format:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; sudo lshw -short -C disk
H/W path         Device     Class          Description
&lt;span class=&quot;o&quot;&gt;======================================================&lt;/span&gt;
/0/1/0.0.0       /dev/sda   disk           500GB Samsung SSD 850
/0/2/0.0.0       /dev/sdb   disk           1TB ST1000DM010-2EP1
/0/3/0.0.0       /dev/sdc   disk           2TB WDC WD20EZRZ-00Z
/0/4/0.0.0       /dev/sdd   disk           1TB Samsung SSD 860

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

&lt;h2 id=&quot;create-a-partition&quot;&gt;Create a Partition&lt;/h2&gt;
&lt;p&gt;If the disk does not have an existing partition, create one.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo fdisk /dev/sdd
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Follow instructions, hit all defaults to create one large partition…it will be /dev/sdd1.&lt;/p&gt;

&lt;p&gt;If the disk is already partitioned, you can use an existing partition. Note that all data will be over-written.&lt;/p&gt;

&lt;h2 id=&quot;luks-encryption&quot;&gt;LUKS Encryption&lt;/h2&gt;
&lt;p&gt;Next step is to LUKS encrypt the target partition - in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdd1&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cryptsetup -y -v luksFormat /dev/sdd1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-v&lt;/code&gt;: verbose output&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-y&lt;/code&gt;: Forces double entry from the user when interactively setting the passphrase - ask for it twice and complain if both inputs do not match&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;create-a-mapping&quot;&gt;Create a Mapping&lt;/h2&gt;
&lt;p&gt;The encrypted partition is accessed by means of a mapping.&lt;/p&gt;

&lt;p&gt;To create a mapping for the current session:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Creates a mapping called backupSSD&lt;/span&gt;
sudo cryptsetup luksOpen /dev/sdd1 backupSSD

&lt;span class=&quot;c&quot;&gt;# Check:&lt;/span&gt;
ls -l /dev/mapper/backupSSD
lrwxrwxrwx 1 root root 7 Dec 17 15:48 /dev/mapper/backupSSD -&amp;gt; ../dm-6

&lt;span class=&quot;c&quot;&gt;# Check mapping status&lt;/span&gt;
sudo cryptsetup -v status backupSSD
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sudo] password &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;david:
/dev/mapper/backupSSD is active and is &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;use.
  &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 256 bits
  device:  /dev/sdd1
  offset:  4096 sectors
  size:    1953519024 sectors
  mode:    &lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt;/write
Command successful.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;This mapping is not persistent&lt;/strong&gt;. If you want to open the disk/partition automatically on boot, you will need to amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/crypttab&lt;/code&gt; to set up a mapped device name.&lt;/p&gt;

&lt;h2 id=&quot;crypttab&quot;&gt;Crypttab&lt;/h2&gt;
&lt;p&gt;The file &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/crypttab&lt;/code&gt; contains descriptive information about encrypted filesystems. Each filesystem is described on a separate line.&lt;/p&gt;

&lt;p&gt;Fields on each line are separated by tabs or spaces. The order of records in crypttab is important because the init scripts sequentially iterate through crypttab doing their thing.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# /etc/crypttab&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Mapping name in field 1.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# UUID of partition in field 2&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Full path to keyfile in field 3&lt;/span&gt;
backupSSD &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4f942e15-ff00-4213-aab1-089448b17850 /root/.keyfiles/hdd-1.key luks,discard
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;The first field, target, describes the mapped device name. It must be a plain filename without any directory components. A mapped device which encrypts/decrypts data to/from the source device will be created at /dev/mapper/target by cryptsetup.&lt;/p&gt;

  &lt;p&gt;The second field, source device, describes either the block special device or file that contains the encrypted data. Instead of giving the source deviceexplicitly, the UUID is supported as well, using &lt;code class=&quot;highlighter-rouge&quot;&gt;UUID=&amp;lt;luks_uuid&amp;gt;&lt;/code&gt;.&lt;/p&gt;

  &lt;p&gt;The third field, key file, describes the file to use as a key for decrypting the data of the source device. Note that the entire key file will be used as thepassphrase; the passphrase must not be followed by a newline character.&lt;/p&gt;

  &lt;p&gt;It can also be a device name (e.g. /dev/urandom), note however that LUKS requires a persistent key and therefore does not support random data keys.&lt;/p&gt;

  &lt;p&gt;If the key file is the string “none”, a passphrase will be read interactively from the console. In this case, the options precheck, check, checkargs and triesmay be useful.&lt;/p&gt;

  &lt;p&gt;The fourth field, options, describes the cryptsetup options associated with the encryption process. At minimum, the field should contain either the string luksrespectively tcrypt or the cipher, hash and size options.&lt;/p&gt;

  &lt;p&gt;Options are in the format: key=value [,key=value …]. The supported options are described below.Note that all four fields are mandatory and that a missing field will lead to unspecified behaviour.&lt;/p&gt;

  &lt;p&gt;–Man page: man crypttab&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;luks-header&quot;&gt;LUKS Header&lt;/h2&gt;
&lt;p&gt;Check it using the &lt;code class=&quot;highlighter-rouge&quot;&gt;luksDump&lt;/code&gt; command. Data shown is anonymised (junk):&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo cryptsetup luksDump /dev/sdd1

LUKS header information &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; /dev/sdd1

Version:       	1
Cipher name:   	aes
Cipher mode:   	xts-plain64
Hash spec:     	sha1
Payload offset:	4096
MK bits:       	256
MK digest:     	ad f8 5d b7 ce 4e 54 f6 17 79 a8 ce f5 07 12 ce 82 b1 94 28
MK salt:	&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;44 e4 6a db a0 b4 ba d1 9d c5 da 1b 97 d1 a2
		c8 a5 17 ac 7b 97 50 42 67 84 fe 74 a6 1f 5f d5               	
MK iterations: 	274632
UUID:          	2e72f987-ffa1-c0c0-d144-098f45d86100

Key Slot 0: ENABLED
	Iterations:         	978243
	Salt:               	1e b5 1f 35 7b 46 24 34 ec ab a2 7d 5a 74 ba 38
	                      	87 7e c9 57 b4 d0 2a ab b7 e1 13 32 92 65 b2 c2
	Key material offset:	8
	AF stripes:            	4000
Key Slot 1: ENABLED
	Iterations:         	4456344
	Salt:			39 68 d2 4e 04 51 a3 c2 c9 88 e8 71 a5 a9 0f d4 
	                      	17 3f 88 0c 39 2c f5 22 35 e5 19 48 3c 1b 47 49
	Key material offset:	264
	AF stripes:            	4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Amongst other interesting things, the output will show the size of the master key (&lt;code class=&quot;highlighter-rouge&quot;&gt;MK bits&lt;/code&gt;). A 256 bit master key will equate to a LUKS header size of 1,052,672 Bytes &lt;a href=&quot;https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery&quot;&gt;See the cryptsetup FAQ&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;format-partition&quot;&gt;Format Partition&lt;/h2&gt;
&lt;p&gt;Do not omit this step - or the partition won’t mount.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo mkfs.ext4 /dev/mapper/backupSSD -L &lt;span class=&quot;s2&quot;&gt;&quot;Extra SSD 1TB&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;…where &lt;code class=&quot;highlighter-rouge&quot;&gt;-L&lt;/code&gt; denotes the partition label.&lt;/p&gt;

&lt;h2 id=&quot;mount-point&quot;&gt;Mount Point&lt;/h2&gt;
&lt;p&gt;Create a mount point. Give the mount point appropriate ownership. E.g.:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo mkdir /media/secure-ssd
sudo chown &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /media/secure-ssd
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;mount&quot;&gt;Mount&lt;/h2&gt;
&lt;p&gt;To mount, you need to reference the &lt;strong&gt;mapper&lt;/strong&gt; not the partition:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo mount /dev/mapper/backupSSD /media/secure-ssd
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;auto-mount&quot;&gt;Auto Mount&lt;/h2&gt;
&lt;p&gt;Mount at boot.&lt;/p&gt;

&lt;p&gt;Edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fstab&lt;/code&gt; to reference the mapper to the decrypted volume&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Samsung 860 1TB EVO SSD path installed 17-02-2018&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# mapper              mount-point       type mount-options dump fs_passno&lt;/span&gt;
/dev/mapper/backupSSD /media/secure-ssd ext4 defaults 0 2

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

&lt;p&gt;Mount-options refer to filesystem related parameters, formatted as a comma-separated list. This contains at least the type of &lt;code class=&quot;highlighter-rouge&quot;&gt;mount&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;ro&lt;/code&gt;
or &lt;code class=&quot;highlighter-rouge&quot;&gt;rw&lt;/code&gt;), plus any additional options appropriate to the filesystem type (including performance-tuning options). Basic filesystem-independent options are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;defaults&lt;/code&gt; - use default options: rw, suid, dev, exec, auto, nouser, and async.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;noauto&lt;/code&gt; - do not mount when “mount -a” is given (e.g., at boot time)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;user&lt;/code&gt; - allow a user to mount&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;owner&lt;/code&gt; - allow device owner to mount&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;comment&lt;/code&gt; - or x-&lt;name&gt; for use by fstab-maintaining programs&lt;/name&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nofail&lt;/code&gt; - do not report errors for this device if it does not exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sixth field (&lt;code class=&quot;highlighter-rouge&quot;&gt;fs_passno&lt;/code&gt;) is used by fsck to determine the order in which filesystem checks are done at boot time.&lt;/p&gt;

&lt;p&gt;The root filesystem should be specified with a &lt;code class=&quot;highlighter-rouge&quot;&gt;fs_passno&lt;/code&gt; of 1. Other filesystems should have a &lt;code class=&quot;highlighter-rouge&quot;&gt;fs_passno&lt;/code&gt; of 2. Filesystems within a drive will be checked sequentially, but filesystems on
different drives will be checked at the same time to utilize parallelism available in the hardware. Defaults to zero (don’t fsck) if not present.&lt;/p&gt;

&lt;h2 id=&quot;decrypt-using-a-key&quot;&gt;Decrypt using a key&lt;/h2&gt;
&lt;p&gt;I set up additonal drives to mount &amp;amp; decrypt automatically by means of a keyfile held in my encrypted boot drive. This means that I just decrypt the primary disk at start up, with a passphrase as usual. The keyfile is then used to decrypt additional disks automatically. Keyfiles are secure since the drive holding the keyfile is encrypted.&lt;/p&gt;

&lt;p&gt;Cryptsetup allows you to specify up to 8 keyslots - passwords or keyfiles. When you add these, they are hashed and added to key-slots in the LUKS header at the start of the device. When you first run &lt;code class=&quot;highlighter-rouge&quot;&gt;luksFormat&lt;/code&gt;, the initial password you supply is hashed and stored in key-slot 0 of the LUKS header. You can easily add an additional passphrase, and this can take the form of a keyfile. This means that the volume can be decrypted either with the initial passphrase or the keyfile.&lt;/p&gt;

&lt;p&gt;To add a password to a LUKS partition, you need an unencrypted copy of the master key - so if the partition is not initialized, you will be prompted for the original passphrase. Because more than one password is possible under LUKS setups, the wording of the password prompt may seem confusing - it says: “Enter any passphrase”. This means enter any valid existing password for the partition.&lt;/p&gt;

&lt;p&gt;Create a keyfile:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Make an appropriate directory&lt;/span&gt;
sudo mkdir /root/.keyfiles

&lt;span class=&quot;c&quot;&gt;# Make a keyfile of randomly sourced bytes&lt;/span&gt;
sudo dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/urandom &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/.keyfiles/hdd-1.key &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1024 &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4

&lt;span class=&quot;c&quot;&gt;# Make this read-only by owner (in this case, root):&lt;/span&gt;
sudo chmod 0400 /root/.keyfiles/hdd-1.key
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Set up a keyfile for the LUKS partition (in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdd1&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo cryptsetup luksAddKey /dev/sdd1 /root/.keyfiles/hdd-1.key
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To automatically mount at boot, the mapping in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/crypttab&lt;/code&gt; should reference the keyfile:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Modify line to /etc/crypttab if the keyfile has not been added&lt;/span&gt;
backupSSD &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4f942e15-ff00-4213-aab1-089448b17850 /root/.keyfiles/hdd-1.key luks,discard
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;unmount--secure&quot;&gt;Unmount &amp;amp; Secure&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;umount /dev/mapper/backupSSD
cryptsetup luksClose backupSSD
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Decrypt &amp;amp; remount:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cryptsetup luksOpen /dev/sdd1 backupSSD
&lt;span class=&quot;c&quot;&gt;# mount /dev/mapper/backupSSD /media/mountpoint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://www.loganmarchione.com/2015/05/encrypted-external-drive-with-luks/&quot;&gt;Good image of LUKS header&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;check-passphrase&quot;&gt;Check Passphrase&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo cryptsetup luksOpen --test-passphrase /dev/sdX &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;correct

&lt;span class=&quot;c&quot;&gt;# Prompts for password, echoes &quot;correct&quot; if successful&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Alternative - specify slot&lt;/span&gt;
cryptsetup luksOpen --test-passphrase --key-slot 0 /dev/sdX &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;correct
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;backup-header-files&quot;&gt;Backup Header Files&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo cryptsetup luksHeaderBackup --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sda3 /dev/sda3
sudo cryptsetup luksHeaderBackup --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdb /dev/sdb
sudo cryptsetup luksHeaderBackup --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdc2 /dev/sdc2
sudo cryptsetup luksHeaderBackup --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdd1 /dev/sdd1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;restore-header-files&quot;&gt;Restore Header Files&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# General form:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# cryptsetup luksHeaderRestore --header-backup-file &amp;lt;file&amp;gt; &amp;lt;device&amp;gt;&lt;/span&gt;

sudo cryptsetup luksHeaderRestore --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sda3 /dev/sda3
sudo cryptsetup luksHeaderRestore --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdb /dev/sdb
sudo cryptsetup luksHeaderRestore --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdc2 /dev/sdc2
sudo cryptsetup luksHeaderRestore --header-backup-file ~/backup-dir/LUKS-headers/my-hostname/sdd1 /dev/sdd1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;breaking-luks-encryption&quot;&gt;Breaking LUKS Encryption&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://0x00sec.org/t/breaking-encryption-hashed-passwords-luks-devices/811&quot;&gt;This article&lt;/a&gt; describes a method for breaking LUKS encryption that involves dumping the contents of memory while running &lt;code class=&quot;highlighter-rouge&quot;&gt;cryptsetup luksOpen&lt;/code&gt;, and then finding the hashed password. Once an adversary has a copy of the hashed password, they can run it through a password cracker. The method relies on the fact that the hashed password is loaded into memory by cyrptsetup as part of the authentication process. I haven’t checked this vulnerability, but it certainly sounds plausible.&lt;/p&gt;

&lt;p&gt;To prevent such an attack, use a complex password. My personal preference is for a memorised &amp;gt; 12 character mneumonic passsphrase drawn from a possible keyspace of 94 (upper &amp;amp; lowercase, number, special character), with additional padding characters to increase overall length up to 22. If you encrypt disks with LUKS and then select “password123” as your passphrase, you may as well not bother.&lt;/p&gt;

&lt;h2 id=&quot;appendix&quot;&gt;Appendix&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; is a straightforward and concise way to get all available drives &amp;amp; partitions. LUKS partitions/drives have the FSTYPE &lt;code class=&quot;highlighter-rouge&quot;&gt;crypto_LUKS&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;david@ubuntu:$ &lt;/span&gt;sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID

NAME                 FSTYPE        SIZE MOUNTPOINT              LABEL         UUID
sda                              465.8G
├─sda1               vfat          512M /boot/efi                             xxx
├─sda2               ext2          488M /boot                                 xxx
└─sda3               crypto_LUKS 464.8G                                       xxx
  └─sda3_crypt       LVM2_member 464.8G                                       xxx
    ├─ubuntu--vg-root
    │                ext4        448.8G /                                     xxx
    └─ubuntu--vg-swap_1
                     swap           16G                                       xxx
      └─cryptswap1   swap           16G &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;SWAP]                                xxx
sdb                  crypto_LUKS 931.5G                                       xxx
└─sdb_crypt          ext4        931.5G /media/secure-hdd-2     Barracuda 1TB xxx
sdc                                1.8T
├─sdc1               ext4        994.9G /media/datadrive        Public HD     xxx
└─sdc2               crypto_LUKS 868.2G                                       xxx
  └─sdc2_crypt       ext4        868.2G /media/secure-hdd       Secure HD     xxx
sdd                              931.5G
└─sdd1               crypto_LUKS 931.5G                                       xxx
  └─backupSSD        ext4        931.5G /media/secure-ssd       Extra SSD 1TB xxx
loop0                squashfs     83.8M /snap/core/3604
loop1                squashfs    178.2M /snap/atom/111
loop2                squashfs     83.8M /snap/core/3748
loop3                squashfs    174.2M /snap/atom/116
loop4                squashfs    178.2M /snap/atom/112
loop5                squashfs     81.3M /snap/core/3887
loop6                squashfs     28.1M /snap/telegram-latest/4
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Available columns (for –output):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;NAME&lt;/code&gt;:  device name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;KNAME&lt;/code&gt;:  internal kernel device name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MAJ&lt;/code&gt;::MIN  major:minor device number&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;FSTYPE&lt;/code&gt;:  filesystem type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MOUNTPOINT&lt;/code&gt;:  where the device is mounted&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LABEL&lt;/code&gt;:  filesystem LABEL&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;UUID&lt;/code&gt;:  filesystem UUID&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PARTTYPE&lt;/code&gt;:  partition type UUID&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PARTLABEL&lt;/code&gt;:  partition LABEL&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PARTUUID&lt;/code&gt;:  partition UUID&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PARTFLAGS&lt;/code&gt;:  partition flags&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RA&lt;/code&gt;:  read-ahead of the device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RO&lt;/code&gt;:  read-only device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RM&lt;/code&gt;:  removable device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HOTPLUG&lt;/code&gt;:  removable or hotplug device (usb, pcmcia, …)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MODEL&lt;/code&gt;:  device identifier&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SERIAL&lt;/code&gt;:  disk serial number&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIZE&lt;/code&gt;:  size of the device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;STATE&lt;/code&gt;:  state of the device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OWNER&lt;/code&gt;:  user name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;GROUP&lt;/code&gt;:  group name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MODE&lt;/code&gt;:  device node permissions&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ALIGNMENT&lt;/code&gt;:  alignment offset&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;MIN&lt;/code&gt;:-IO  minimum I/O size&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OPT&lt;/code&gt;:-IO  optimal I/O size&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PHY&lt;/code&gt;:-SEC  physical sector size&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LOG&lt;/code&gt;:-SEC  logical sector size&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ROTA&lt;/code&gt;:  rotational device&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED&lt;/code&gt;:  I/O scheduler name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RQ&lt;/code&gt;:-SIZE  request queue size&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;TYPE&lt;/code&gt;:  device type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;DISC&lt;/code&gt;:-ALN  discard alignment offset&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;DISC&lt;/code&gt;:-GRAN  discard granularity&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;DISC&lt;/code&gt;:-MAX  discard max bytes&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;DISC&lt;/code&gt;:-ZERO  discard zeroes data&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;WSAME&lt;/code&gt;:  write same max bytes&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;WWN&lt;/code&gt;:  unique storage identifier&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RAND&lt;/code&gt;:  adds randomness&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;PKNAME&lt;/code&gt;:  internal parent kernel device name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HCTL&lt;/code&gt;:  Host:Channel:Target:Lun for SCSI&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;TRAN&lt;/code&gt;:  device transport type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SUBSYSTEMS&lt;/code&gt;:  de-duplicated chain of subsystems&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;REV&lt;/code&gt;:  device revision&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;VENDOR&lt;/code&gt;:  device vendor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cyberciti.biz/hardware/howto-linux-hard-disk-encryption-with-luks-cryptsetup-command/&quot;&gt;Guide on LUKS cryptsetup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://linuxconfig.org/how-to-name-label-a-partition-or-volume-on-linux&quot;&gt;Labelling of partitions/volumes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.howtogeek.com/106873/how-to-use-fdisk-to-manage-partitions-on-linux/&quot;&gt;Using fdisk to manage partitions on Linux&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery&quot;&gt;FAQ for cryptsetup&lt;/a&gt; - &lt;strong&gt;essential reading&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://shaakunthala.wordpress.com/2017/11/27/how-to-create-an-encrypted-luks-disk-image/&quot;&gt;Create an encrypted LUKS disk&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.loganmarchione.com/2015/05/encrypted-external-drive-with-luks/&quot;&gt;Encrypt external drives with LUKS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://0x00sec.org/t/breaking-encryption-hashed-passwords-luks-devices/811&quot;&gt;Breaking LUKS encryption&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://access.redhat.com/solutions/1543373&quot;&gt;Useful article from RedHat on recovering lost LUKS key/passphrase&lt;/a&gt; (spoiler - you probably can’t recover if the drive is encrypted and the password is strong)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://shaakunthala.wordpress.com/2017/12/22/luks-important-header-backup/&quot;&gt;Backup LUKS headers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

</description>
        <pubDate>Tue, 01 Dec 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/12/LUKS-Encrypt-Hard-Drive-with-Cryptsetup-on-Ubuntu-20.04/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/12/LUKS-Encrypt-Hard-Drive-with-Cryptsetup-on-Ubuntu-20.04/</guid>
      </item>
      
    
      
      <item>
        <title>Bitcoin Pay To Script Hash</title>
        <description>&lt;p&gt;Transaction outputs do not need to be sent to a Bitcoin public key - they can be sent to a script hash.&lt;/p&gt;

&lt;p&gt;This process, known as Pay To Script Hash (P2SH) allows complex spending conditions to be attached to a UTXO in a way that does not increase the size of the transaction and which places the burden of complexity on the receiver.&lt;/p&gt;

&lt;p&gt;P2SH involves:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The receiver generating a set of spending conditions - the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The receiver generating a Bitcoin address by hashing the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; and encoding this in an address format&lt;/li&gt;
  &lt;li&gt;The sender sending funds to the address, with funds locked according to the conditions set in step 1&lt;/li&gt;
  &lt;li&gt;Spending the transferred funds - the receiver must provide a valid &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; the hash of which matches that represented by the address, after which the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; is executed as a locking script.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;
&lt;p&gt;All transaction outputs create a cryptographic puzzle that must be solved in order to spend the output. The puzzle and the solution to the puzzle are represented by two scripts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt;: The locking script which specifies the conditions which must be met for the output to be spent&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt;: This contains a signature that unlocks the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt; - if the transaction is Pay To Public Key Hash, this is a cryptographic proof that the spender controls the private key associated with the address public key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a Pay-To-Script-Hash (P2SH) transaction, the conditions to redeem the transaction are encoded in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; rather than in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt;. The &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt; contains the hash and opcodes necessary to check that the spenders &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; matches the original script used to generate the Bitcoin address. Once this has been checked, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; (present in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt;) is permitted to execute.&lt;/p&gt;

&lt;p&gt;In this way, the conditions required to spend the UTXO are shifted to the receiver of the funds (i.e. the &lt;em&gt;input&lt;/em&gt; in the spending transaction).&lt;/p&gt;

&lt;p&gt;This has several benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The sender can send without concerning themselves with the spending conditions specified by the receiver - the sender focuses solely on transferring funds to the receiver&lt;/li&gt;
  &lt;li&gt;For multi-signature transactions, funds are sent without exposing the public keys of the recipient(s) - this increases privacy since these public keys are not exposed until the recipient spends the funds&lt;/li&gt;
  &lt;li&gt;The receiving address is short compared to a full redeemScript - typically a 34 character base58Check encoded address&lt;/li&gt;
  &lt;li&gt;UTXOs do not contain long locking scripts - the burden is shifted to transaction inputs which are stored in the blockchain, reducing the memory footprint of the UTXO set&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;The purpose of pay-to-script-hash is to move the responsibility for supplying the conditions to redeem a transaction from the sender of the funds to the redeemer.&lt;/p&gt;

  &lt;p&gt;The benefit is allowing a sender to fund any arbitrary transaction, no matter how complicated, using a fixed-length 20-byte hash that is short enough to scan from a QR code or easily copied and pasted. 
— &lt;a href=&quot;https://en.bitcoin.it/wiki/BIP_0016&quot;&gt;BIP 0016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;locking-steps&quot;&gt;Locking Steps&lt;/h2&gt;
&lt;p&gt;The receiver decides the spending conditions for the funds that they will receive. These conditions are bounded by what is possible in a regular Bitcoin script.&lt;/p&gt;

&lt;p&gt;Create a multi-sig script. For example, 2 of 3 multisig:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;OP_2 &amp;lt;pubKey 1&amp;gt; &amp;lt;pubKey2&amp;gt; &amp;lt;pubKey3&amp;gt; OP_3 OP_CHECKMULTISIG
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The hash of the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; is computed by SHA256 hashing the serialized byte format, followed by RIPEMD160 hashing the result.&lt;/p&gt;

&lt;h3 id=&quot;the-address&quot;&gt;The Address&lt;/h3&gt;
&lt;p&gt;The receiver creates an address by converting the hash of the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; into a base 58 Bitcoin address by Base58Check. From the serialized byte format of the script the process is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SHA256 hash the serialized bytes of the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;RIPEMD160 hash the result&lt;/li&gt;
  &lt;li&gt;Prepend a version byte: &lt;code class=&quot;highlighter-rouge&quot;&gt;0x05&lt;/code&gt; for mainnet, &lt;code class=&quot;highlighter-rouge&quot;&gt;0xc4&lt;/code&gt; for testnet/regtest&lt;/li&gt;
  &lt;li&gt;Create a checksum by double SHA256 hashing the RIPEMD160 hash, and appending the first four bytes of this value to the RIPEMD160 hash&lt;/li&gt;
  &lt;li&gt;Encode the RIPEMD160 + checksum hash into base 58.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;scriptPubKey&lt;/code&gt; of the transaction output will be:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;OP_HASH160 &amp;lt;redeemScriptHash&amp;gt; OP_EQUAL
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;worked-example-2-of-3-multisig-as-a-p2sh&quot;&gt;Worked Example: 2 of 3 Multisig as a P2SH&lt;/h2&gt;
&lt;p&gt;Create a 2-of-3 Multisignature address and send coins to the address.&lt;/p&gt;

&lt;h3 id=&quot;step-1-construct-the-multisig-script&quot;&gt;Step 1: Construct the Multisig Script&lt;/h3&gt;
&lt;p&gt;The Multisig script requires the public keys that will be used to lock the output, as well as the total number of public keys used ($n$) and the threshold number of keys required for the funds to be unlocked ($m$).&lt;/p&gt;

&lt;p&gt;To create the multisig:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Make an array of public keys to be used - not strictly necessary, but handling keys&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# in this way makes the command much cleaner:&lt;/span&gt;
pubkeys[0]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;02c3eb5147ead06273e48b71fb2ce3e0f1484b3222c75b2039beb720c480ecb00c &lt;span class=&quot;c&quot;&gt;# first&lt;/span&gt;
pubkeys[1]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;02b6d8bd0cd403f488df6dccc5281c61029052a31d6ce57a0d6dcb64890a4ea814 &lt;span class=&quot;c&quot;&gt;# second&lt;/span&gt;
pubkeys[2]&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0234965dbaff057b7a1fd08b8e40b3117c23abaa05345ab3cedf129c0c50b17e5f &lt;span class=&quot;c&quot;&gt;# third&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Create a multisig redeem script using these keys. The jq utility is used to pass the full array pubkeys&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# into the command in the required JSON format:&lt;/span&gt;
bitcoin-cli -regtest createmultisig 2 &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;jq -nc &lt;span class=&quot;s1&quot;&gt;'$ARGS.positional'&lt;/span&gt; --args &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pubkeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# If you'd rather not use jq, escape the quotations within the JSON array:&lt;/span&gt;
bitcoin-cli -regtest createmultisig 2 &lt;span class=&quot;s2&quot;&gt;&quot;[&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pubkeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pubkeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[1]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pubkeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[2]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;]&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# These commands are effectively identical. The result is:&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;address&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;2N2Zxm7Kf3v4DKMSWW3zYz5Szi8tmGCvtKx&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;redeemScript&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;522102c3eb5147ead06273e48b71fb2ce3e0f1484b3222c75b2039beb720c480ecb00c2102b6d8bd0cd403f488df6dccc5281c61029052a31d6ce57a0d6dcb64890a4ea814210234965dbaff057b7a1fd08b8e40b3117c23abaa05345ab3cedf129c0c50b17e5f53ae&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;descriptor&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;sh(multi(2,02c3eb5147ead06273e48b71fb2ce3e0f1484b3222c75b2039beb720c480ecb00c,02b6d8bd0cd403f488df6dccc5281c61029052a31d6ce57a0d6dcb64890a4ea814,0234965dbaff057b7a1fd08b8e40b3117c23abaa05345ab3cedf129c0c50b17e5f))#q6zdklmm&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;redeemScript&lt;/code&gt; is constructed by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Setting the first byte to an &lt;a href=&quot;https://en.bitcoin.it/wiki/Script&quot;&gt;opcode&lt;/a&gt; that pushes the number $m$ (the threshold) onto the stack - in this case 0x52 (an instruction to “push the number 2 onto the stack”)&lt;/li&gt;
  &lt;li&gt;The next byte is in the range 0x01-0x4b, which denotes that this value is the next number of bytes to be pushed to the stack
    &lt;ul&gt;
      &lt;li&gt;In the case of a multisig redeem script, this byte is 0x21, which denotes that the following 33 bytes are to be pushed onto the stack&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The next bytes to be added are the first public key&lt;/li&gt;
  &lt;li&gt;Steps 2 and 3 are repeated until all public keys have been added to the script&lt;/li&gt;
  &lt;li&gt;After the final key, the next byte is an opcode that pushes the number $n$ (the total number of public keys) onto the stack - in this case, 0x53 (an instruction to “push the number 3 onto the stack”)&lt;/li&gt;
  &lt;li&gt;Finally the opcode &lt;code class=&quot;highlighter-rouge&quot;&gt;OP_CHECKMULTISIG&lt;/code&gt; is added - the value 0xae&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The address for the multisig is computed by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;SHA256 hash the input bytes - the input bytes are the bytes of the entire redeem script as described above&lt;/li&gt;
  &lt;li&gt;RIPEMD160 the result of step 1&lt;/li&gt;
  &lt;li&gt;Prepend the network byte to the hash&lt;/li&gt;
  &lt;li&gt;Perform SHA256 twice on the concatenated &lt;code class=&quot;highlighter-rouge&quot;&gt;(network byte || RIPEMD160 hash)&lt;/code&gt; - the checksum is the first four bytes of the result.&lt;/li&gt;
  &lt;li&gt;Append the 4 byte checksum to the concatenated &lt;code class=&quot;highlighter-rouge&quot;&gt;(network byte || RIPEMD160 hash)&lt;/code&gt;, resulting in 25 bytes&lt;/li&gt;
  &lt;li&gt;Base58 encode the result&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;storage-in-chainstate-db-utxo&quot;&gt;Storage in Chainstate DB: UTXO&lt;/h2&gt;

&lt;p&gt;The scriptPubKey that is stored in the chainstate database is the value of the hashed redeemScript:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;66445308b05d3eec5aab83dceb5cc87a759bd7d5
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Because we know the script type, the scriptPubKey can be assembled by adding the appropriate opcodes:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;OP_HASH160  Push next 0x14 bytes    data                                        OP_EQUAL    
a9          14                      66445308b05d3eec5aab83dceb5cc87a759bd7d5    87
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;compute-address&quot;&gt;Compute address&lt;/h3&gt;
&lt;p&gt;Get address from UTXO:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;extract hash from DB&lt;/li&gt;
  &lt;li&gt;Prepend network designator byte (0xc4 for regtest)&lt;/li&gt;
  &lt;li&gt;Compute checksum and append&lt;/li&gt;
  &lt;li&gt;Base58 encode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network Byte    data                                        Checksum
c4              66445308b05d3eec5aab83dceb5cc87a759bd7d5b7  86084f&lt;/p&gt;

&lt;p&gt;Expressed as Base58:
2N2Zxm7Kf3v4DKMSWW3zYz5Szi8tmGCvtKx&lt;/p&gt;

&lt;h2 id=&quot;process-of-spending&quot;&gt;Process of Spending&lt;/h2&gt;
&lt;p&gt;The conditions specified in an output &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt; must be met to spend the funds contained in that output.&lt;/p&gt;

&lt;p&gt;The locking script - &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt; is a hash of the original custom locking script (&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScriptHash&amp;gt;&lt;/code&gt;) prepended with the &lt;code class=&quot;highlighter-rouge&quot;&gt;OP_HASH160&lt;/code&gt; opcode and appended with the &lt;code class=&quot;highlighter-rouge&quot;&gt;OP_EQUAL&lt;/code&gt; opcode.&lt;/p&gt;

&lt;p&gt;The spending input must provide the original &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; along with the required number of signatures as a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once it has been verified that the hash of the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; is equal to the hash contained in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt;, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; provided in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; can be deserialized and processed. If the provided signatures match, the transaction is considered valid and the funds can be spent.&lt;/p&gt;

&lt;p&gt;The mechanics of this involve the protocol concatenating &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt; and running the entire script. If the final result evaluates to true, the transaction is valid. If at any point the script evaluation fails, the transaction is considered invalid and is discarded.&lt;/p&gt;

&lt;h3 id=&quot;step-1-add-scriptsig-to-stack&quot;&gt;Step 1: Add scriptSig to Stack&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; consists of the serialized &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; and the required signatures. This is pushed onto the stack:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Stack&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;sig 2&amp;gt;&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;sig 1&amp;gt;&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;At this point, a copy is made of the stack - this measure is peculiar to P2SH scripts.&lt;/p&gt;

&lt;p&gt;The original locking script (&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptPubKey&amp;gt;&lt;/code&gt;) is now run:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OP_HASH160 0x14 &amp;lt;redeemScriptHash&amp;gt; OP_EQUAL&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OP_HASH160&lt;/code&gt;: The top item (&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt;) is popped off the stack, hashed with &lt;code class=&quot;highlighter-rouge&quot;&gt;RIPEMD160(SHA256())&lt;/code&gt; (the same hashing process used to generate the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScriptHash&amp;gt;&lt;/code&gt; provided by the locking script) and pushed back onto the stack.&lt;/li&gt;
  &lt;li&gt;The next 0x14 bytes (the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScriptHash&amp;gt;&lt;/code&gt;) are pushed onto the stack&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;OP_EQUAL&lt;/code&gt; is executed - the top two elements are popped from the stack and compared. If they are equal, the integer 1 is pushed onto the stack. Otherwise, a zero is pushed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, if the stack contains the value 1, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; supplied by the unlocking &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; matches the original script contained within the locking script, and execution can continue. Otherwise, execution stops at this point.&lt;/p&gt;

&lt;h3 id=&quot;step-2-execution-of-redeemscript&quot;&gt;Step 2: Execution of redeemScript&lt;/h3&gt;
&lt;p&gt;Once it has been determined that the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; matches the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScriptHash&amp;gt;&lt;/code&gt;, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; provided by the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;scriptSig&amp;gt;&lt;/code&gt; is deserialized and considered as a locking script to be run against the signatures. This is achieved by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Operating on the copy of the stack that was made in step 1&lt;/li&gt;
  &lt;li&gt;Popping the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; and deserializing it&lt;/li&gt;
  &lt;li&gt;Executing the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;redeemScript&amp;gt;&lt;/code&gt; against the stack contents&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.bitcoin.org/examples/transactions.html#p2sh-multisig&quot;&gt;Worked example, P2SH Multisig Transaction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitcoin.stackexchange.com/a/52272/56514&quot;&gt;SO Answer&lt;/a&gt;, David Harding&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://learnmeabitcoin.com/technical/p2sh&quot;&gt;P2SH on Learn Me A Bitcoin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 18 Nov 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/11/Bitcoin-Pay-To-Script-Hash/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/11/Bitcoin-Pay-To-Script-Hash/</guid>
      </item>
      
    
      
      <item>
        <title>Access YAML Values from Frontmatter Using Python</title>
        <description>&lt;p&gt;Access nested (or not) YAML values using Python. Used within a Makefile to set variables from either Markdown frontmatter or YAML config files.&lt;/p&gt;

&lt;p&gt;Uses the Python 3 &lt;code class=&quot;highlighter-rouge&quot;&gt;yaml&lt;/code&gt; module’s &lt;code class=&quot;highlighter-rouge&quot;&gt;load_all&lt;/code&gt; method - this is necessary if accessing YAML within a frontmatter block (e.g. at the start of a markdown file), since the normal frontmatter delimiters cause the Python module to treat the YAML block as the first in a series of YAML documents.&lt;/p&gt;

&lt;p&gt;The function receives a list of YAML keys &lt;code class=&quot;highlighter-rouge&quot;&gt;key_list&lt;/code&gt; ordered from highest to lowest level, allowing access to nested elements.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Rocky&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;line 1&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;22 Acacia Ave&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;line 2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;London&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To access the value “London”, run &lt;code class=&quot;highlighter-rouge&quot;&gt;./yaml_access.py file.md address &quot;line 2&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To access the value “Rocky”, run &lt;code class=&quot;highlighter-rouge&quot;&gt;./yaml_access.py file.md name&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# yaml_access.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;yaml&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;project_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;realpath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filepath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Make a dict from the first YAML block&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Loader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FullLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
	
        &lt;span class=&quot;c&quot;&gt;# If there are multiple keys, we need to step down a hierarchy of keys&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# to reach the correct value. At each iteration, set data to be a new&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# simpler dict (or the final value if we're at the last key) by accessing&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# the value by it's key.  &lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 04 Nov 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/11/access-yaml-values-from-frontmatter-using-python/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/11/access-yaml-values-from-frontmatter-using-python/</guid>
      </item>
      
    
      
      <item>
        <title>Build Bitcoin Core in Ubuntu</title>
        <description>&lt;p&gt;This article describes how to clone, configure, make and install Bitcoin Core on a newly installed Ubuntu 20.04 Focal Fossa operating system.&lt;/p&gt;

&lt;p&gt;If you’re not a native Linux user, you could consider building and running Bitcoin Core in a Linux virtual machine using something like VirtualBox or a suitable Docker image.&lt;/p&gt;

&lt;h2 id=&quot;install-required-build-tools&quot;&gt;Install Required Build Tools&lt;/h2&gt;
&lt;p&gt;There are a number of software tools that are necessary for the build process.&lt;/p&gt;

&lt;p&gt;Assuming a completely fresh Ubuntu install, you need to install the required build tools, as outlined in &lt;code class=&quot;highlighter-rouge&quot;&gt;doc/build-unix.md&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt git install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;clone-bitcoin-core&quot;&gt;Clone Bitcoin Core&lt;/h2&gt;
&lt;p&gt;Clone the Bitcoin Core codebase and move into the project directory:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/bitcoin/bitcoin.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;bitcoin
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Bitcoin Core has a number of dependencies - it relies on other pieces of software to work and these must be available when compiling Bitcoin Core binaries.&lt;/p&gt;

&lt;p&gt;You can either:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Install dependencies system-wide using the Ubuntu package management system - see the following note for a caveat&lt;/li&gt;
  &lt;li&gt;Build them yourself and reference them appropriately during the Bitcoin Core build process&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second option may be best if you need to ensure compatibility with wallets generated by the distributed binaries, which are compiled with BerkeleyDB version 4.8.&lt;/p&gt;

&lt;p&gt;This is incompatible with the version of BerkeleyDB distributed by Ubuntu - which is likely to be version 5.1 or greater. This means that if you use the Ubuntu package manager to install BerkeleyDB (using &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt install libdb-dev libdb++-dev&lt;/code&gt;) the wallet that you generate will be incompatible with wallets generated by the distributed binaries.&lt;/p&gt;

&lt;p&gt;If you choose to do this, you’ll need to pass the &lt;code class=&quot;highlighter-rouge&quot;&gt;--with-incompatible-bdb&lt;/code&gt; option to the &lt;code class=&quot;highlighter-rouge&quot;&gt;configure&lt;/code&gt; script.
I’ve also had problems in the past with incompatible Boost library versions - so if you’re building Bitcoin on a development machine, it might be better to build dependencies. If you do self-build dependencies, you avoid all incompatibility hassles. On the other hand, the build process for dependencies adds to the total build time considerably.&lt;/p&gt;

&lt;p&gt;If you are building from self-compiled dependencies, skip the “install required dependencies” in the Bitcoin Core &lt;code class=&quot;highlighter-rouge&quot;&gt;build-unix.md&lt;/code&gt; instructions.&lt;/p&gt;

&lt;h2 id=&quot;build-dependencies&quot;&gt;Build Dependencies&lt;/h2&gt;
&lt;p&gt;To build dependencies for the current architecture &amp;amp; OS, move into the &lt;code class=&quot;highlighter-rouge&quot;&gt;depends&lt;/code&gt; subdirectory and:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Install dependencies required for the build process&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Move into the depends subdirectory&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;bitcoin/depends

&lt;span class=&quot;c&quot;&gt;# Install the tools required in order to build dependencies &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Some of the dependencies may already have been installed - if this is the case, they will be ignored by `apt` (or `apt-get`) so don't worry about it.&lt;/span&gt;
sudo apt install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch

&lt;span class=&quot;c&quot;&gt;# Bitcoin core provides a suitable Makefile that makes self-building of dependencies straightforward: &lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/bitcoin/depends
make
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;At this point you may want to go and make a cup of tea because this step is going to take some time. Amongst other packages, this process downloads and builds:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Berekely DB 4.8.3&lt;/li&gt;
  &lt;li&gt;Boost 1.70.0&lt;/li&gt;
  &lt;li&gt;QT&lt;/li&gt;
  &lt;li&gt;QR Encode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the process has finished, you will have an architecture/OS specific directory in the &lt;code class=&quot;highlighter-rouge&quot;&gt;depends&lt;/code&gt; subdirectory.&lt;/p&gt;

&lt;p&gt;In the case of Ubuntu 20.04 on a modern PC with an x86 processor, this will likely be in a directory named &lt;code class=&quot;highlighter-rouge&quot;&gt;x86_64-pc-linux-gnu&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To configure for building, move back up into the project directory:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;configure&quot;&gt;Configure&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;configure&lt;/code&gt; command creates the necessary Makefiles. It allows you to configure(!) the build process.&lt;/p&gt;

&lt;p&gt;To generate the &lt;code class=&quot;highlighter-rouge&quot;&gt;configure&lt;/code&gt; script, move into the bitcoin core project directory and run:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./autogen.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;configure&lt;/code&gt; script guesses values for system dependent variables. If you have self-built dependencies you need to set the &lt;code class=&quot;highlighter-rouge&quot;&gt;--prefix&lt;/code&gt; command option to the directory that was created when building dependencies (i.e. when &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; was run in the &lt;code class=&quot;highlighter-rouge&quot;&gt;depends&lt;/code&gt; sub-directory). This tells the configure script to pick up libraries, tools and settings from the depends build: &lt;code class=&quot;highlighter-rouge&quot;&gt;--prefix=PREFIX&lt;/code&gt; instructs the configure script to install architecture-independent files in &lt;code class=&quot;highlighter-rouge&quot;&gt;PREFIX&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It also means that the generated binaries will be located in a &lt;code class=&quot;highlighter-rouge&quot;&gt;bin&lt;/code&gt; subdirectory of the prefix dir.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Run configure for self-built dependencies&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# From the bitcoin core directory&lt;/span&gt;
./configure --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PWD&lt;/span&gt;/depends/x86_64-pc-linux-gnu
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;By default, the generated Makefile includes the compile flags &lt;code class=&quot;highlighter-rouge&quot;&gt;-g -O2&lt;/code&gt; - the build includes debugging symbols and is optimized for code size &amp;amp; execution time. You can change this by passing an option to &lt;code class=&quot;highlighter-rouge&quot;&gt;./configure&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Compile without debugging symbols&lt;/span&gt;
./configure &lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-O2&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If the &lt;code class=&quot;highlighter-rouge&quot;&gt;config&lt;/code&gt; script completes successfully, you are ready to run &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; to build the executables.&lt;/p&gt;

&lt;h2 id=&quot;make&quot;&gt;Make&lt;/h2&gt;
&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; to build &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt; if dependencies are met.&lt;/p&gt;

&lt;p&gt;If the &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; process is successful, the following binaries can be found in the &lt;code class=&quot;highlighter-rouge&quot;&gt;src&lt;/code&gt; directory under the project root:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-cli&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-tx&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-wallet&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and in the &lt;code class=&quot;highlighter-rouge&quot;&gt;src/qt&lt;/code&gt; subdirectory:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;make-bitcoind--bitcoin-qt-system-commands&quot;&gt;Make bitcoind &amp;amp; bitcoin-qt System Commands&lt;/h2&gt;
&lt;p&gt;This can be achieved by symlinking the executables in a directory that is present in your command search path: &lt;code class=&quot;highlighter-rouge&quot;&gt;$PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For our purposes, &lt;code class=&quot;highlighter-rouge&quot;&gt;usr/local/bin&lt;/code&gt; is a good choice:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo ln -s ~/bitcoin/src/bitcoin&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;d,-cli&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; /usr/local/bin
sudo ln -s ~/bitcoin/src/qt/bitcoin-qt /usr/local/bin
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Alternatively, run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo make install&lt;/code&gt; in the project core directory after making the project.&lt;/p&gt;

&lt;h2 id=&quot;full-install-instructions-installed-dependencies&quot;&gt;Full Install Instructions, Installed Dependencies&lt;/h2&gt;
&lt;p&gt;If you’re not worried about wallet compatibility, the commands below are probably the easiest way to build a Bitcoin Core node.&lt;/p&gt;

&lt;h3 id=&quot;complete-commands-to-install-bitcoin-core-on-a-new-ubuntu-2004-installation&quot;&gt;Complete commands to install Bitcoin Core on a new Ubuntu 20.04 installation&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Update OS before starting&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
sudo apt update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt upgrade

&lt;span class=&quot;c&quot;&gt;# Install Dependencies&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Build requirements:&lt;/span&gt;
sudo apt install git build-essential libtool autotools-dev automake pkg-config bsdmainutils python3

&lt;span class=&quot;c&quot;&gt;# Install required dependencies&lt;/span&gt;
sudo apt install libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev

&lt;span class=&quot;c&quot;&gt;# Install the BerkeleyDB from Ubuntu repositories:&lt;/span&gt;
sudo apt install libdb-dev libdb++-dev

&lt;span class=&quot;c&quot;&gt;# Optional: upnpc&lt;/span&gt;
sudo apt install libminiupnpc-dev

&lt;span class=&quot;c&quot;&gt;# Optional ZMQ:&lt;/span&gt;
sudo apt install libzmq3-dev

&lt;span class=&quot;c&quot;&gt;# For GUI:&lt;/span&gt;
sudo apt install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools

&lt;span class=&quot;c&quot;&gt;# For QR Code support&lt;/span&gt;
sudo apt install libqrencode-dev

&lt;span class=&quot;c&quot;&gt;# Install Bitcoin&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
git clone https://github.com/bitcoin/bitcoin.git

&lt;span class=&quot;c&quot;&gt;# Move into project directory&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;bitcoin

&lt;span class=&quot;c&quot;&gt;# Config&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Generate config script&lt;/span&gt;
./autogen.sh

&lt;span class=&quot;c&quot;&gt;# Configure, with incompatible BerkeleyDB&lt;/span&gt;
./configure --with-incompatible-bdb

&lt;span class=&quot;c&quot;&gt;# If debugging symbols not required, amend compile flags:&lt;/span&gt;
./configure --with-incompatible-bdb &lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-O2&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ...lot's of checking...&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Make&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
make

&lt;span class=&quot;c&quot;&gt;# Install - sudo is required to install binaries in /usr/local/bin&lt;/span&gt;
sudo make install 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;developer-notes&quot;&gt;Developer Notes&lt;/h2&gt;
&lt;p&gt;If you’re intending to work on Bitcoin Core, you should fork a copy on GitHub, before cloning and building your own fork.&lt;/p&gt;

&lt;p&gt;It you do this, you’ll need to keep your fork in sync with upstream development.&lt;/p&gt;

&lt;h3 id=&quot;configure-remote&quot;&gt;Configure Remote&lt;/h3&gt;
&lt;p&gt;Check current remotes:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will probably output &lt;code class=&quot;highlighter-rouge&quot;&gt;origin&lt;/code&gt;, denoting that your repo has a single remote.&lt;/p&gt;

&lt;p&gt;Configure a Git remote for the upstream (original) repo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote add upstream https://github.com/original-project/original-project.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
origin
upstream
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;sync-local-fork-with-upstream&quot;&gt;Sync Local Fork with Upstream&lt;/h3&gt;
&lt;p&gt;There are now three repositories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;local&lt;/li&gt;
  &lt;li&gt;origin (GitHub, Bitbucket etc)&lt;/li&gt;
  &lt;li&gt;upstream (The original repo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sync from upstream to local, then push changes to origin:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# fetch changes&lt;/span&gt;
git fetch upstream

&lt;span class=&quot;c&quot;&gt;# switch to master branch&lt;/span&gt;
git checkout master

&lt;span class=&quot;c&quot;&gt;# Merge changes from upstream into master&lt;/span&gt;
git merge upstream/master

&lt;span class=&quot;c&quot;&gt;# Push local changes to origin&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/master/depends/README.md&quot;&gt;Notes on self-building dependencies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 19 Oct 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/10/Build-Bitcoin-Core-in-Ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/10/Build-Bitcoin-Core-in-Ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Construct C++ Objects From Stdin</title>
        <description>&lt;h1 id=&quot;objects-from-stdin-c&quot;&gt;Objects From Stdin: C++&lt;/h1&gt;
&lt;p&gt;This project is an example of how &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt; data can be used to construct objects in C++ under Linux.&lt;/p&gt;

&lt;p&gt;Data is input via &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt; either through the terminal or by means of file redirection.&lt;/p&gt;

&lt;p&gt;You could use this as boilerplate for importing data stored in a file into C++ data structures. In this case, data is imported on a line-by-line basis, with each line providing data for a separate object.&lt;/p&gt;

&lt;p&gt;A vector of &lt;code class=&quot;highlighter-rouge&quot;&gt;unique_ptr&lt;/code&gt; to objects is used to store objects.&lt;/p&gt;

&lt;h2 id=&quot;use-case&quot;&gt;Use Case&lt;/h2&gt;
&lt;p&gt;I put this project together to better understand input streams in C++. The aim was to accept input by means of file redirection &lt;em&gt;or&lt;/em&gt; terminal input. I also wanted to switch to terminal input for additional interaction in the event of file redirection input of the main body of data.&lt;/p&gt;

&lt;p&gt;One interesting result of this approach is that you can input data either by means of file redirection or by means of terminal input in the default &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt; way.&lt;/p&gt;

&lt;h2 id=&quot;file-redirection&quot;&gt;File Redirection&lt;/h2&gt;
&lt;p&gt;Redirection in Linux involves changing standard input/output devices.&lt;/p&gt;

&lt;p&gt;Usually, the standard input device &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt; is the keyboard and the standard output device &lt;code class=&quot;highlighter-rouge&quot;&gt;stdout&lt;/code&gt; is the screen.&lt;/p&gt;

&lt;p&gt;This means that in C++ &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin &amp;gt;&amp;gt; input;&lt;/code&gt; accepts input from the keyboard, and &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cout &amp;lt;&amp;lt; output&lt;/code&gt; outputs data to the screen.&lt;/p&gt;

&lt;p&gt;To input data from a file, redirection can be used:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./myProg &amp;lt; input.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the shell streams in the contents of &lt;code class=&quot;highlighter-rouge&quot;&gt;input.txt&lt;/code&gt; to stdin instead of accepting keyboard input from the terminal.&lt;/p&gt;

&lt;h2 id=&quot;terminal-input&quot;&gt;Terminal Input&lt;/h2&gt;
&lt;p&gt;If you run the binary file without supplying data by means of file redirection, the user is required to supply data at the terminal. Data is entered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Line-by-line, with each line representing a separate object (&lt;code class=&quot;highlighter-rouge&quot;&gt;\n&lt;/code&gt; delineates objects).&lt;/li&gt;
  &lt;li&gt;Individual scores are separated by spaces.&lt;/li&gt;
  &lt;li&gt;Input is ended by entering Ctrl-D which is the Linux end-of-file signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;switching-from-file-redirection-to-terminal&quot;&gt;Switching from File Redirection to Terminal&lt;/h2&gt;
&lt;p&gt;When input is redirected from a file, &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; refers to the redirected file. If you need to get input from the terminal at a later stage in the programme, you can assign another input buffer using &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin.rdbuf()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Define an input stream as the terminal for the current process (/dev/tty)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/dev/tty&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Set the streambuf of std::cin as the streambuf of /dev/tty.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// stdin is now /dev/tty - keyboard input.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For a working example, see below:&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;ostream&amp;gt;
#include &quot;record.h&quot; // Defines Record, a custom data type (class)
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c1&quot;&gt;// Create a vector of *Record unique pointers
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;records&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;while&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;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Make a unique pointer to a Record
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_unique&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Record&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Input data to this object - reset object if EOF is indicated
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;break&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;c1&quot;&gt;// Move the object to the array
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;records&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&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;c1&quot;&gt;// Reset stdin to terminal	
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/dev/tty&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
     
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;records&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&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;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Output to tty
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;streambuf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ofstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/dev/tty&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
		
		&lt;span class=&quot;c1&quot;&gt;// This should print to screen even if output is redirected to file.
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Enter index: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Reset the original streambuf to std::cout
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;Record&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;records&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;value: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&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;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ERROR: index out of bounds.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.comi/csknk/file-input-object&quot;&gt;GitHub Repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;std::fstream&lt;/code&gt; is the input/output file stream class. The code above associates the &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/tty&lt;/code&gt; (terminal device) stream with the variable &lt;code class=&quot;highlighter-rouge&quot;&gt;in&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next line sets the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::streambuf&lt;/code&gt; for &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; to the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::streambuf&lt;/code&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;in&lt;/code&gt; which has been set to &lt;code class=&quot;highlighter-rouge&quot;&gt;dev/tty&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The function &lt;code class=&quot;highlighter-rouge&quot;&gt;std::ios::rdbuf()&lt;/code&gt; is used to get and set a stream buffer:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;streambuf* rdbuf() const; // get - returns a pointer to the stream buffer of the object associated with stream
streambuf* rdbuf (streambuf* sb); // sets the object pointed at by sb, clears error flags.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Headers: &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;ios&amp;gt; &amp;lt;iostream&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;streams--stream-buffers&quot;&gt;Streams &amp;amp; Stream Buffers&lt;/h2&gt;
&lt;p&gt;A &lt;em&gt;stream&lt;/em&gt; is a communication channel between a programme and it’s environment.&lt;/p&gt;

&lt;p&gt;Streams involve data flowing from a source to a destination - for example, data may flow from the programme to the screen, or may be read from the user’s keyboard into the programme.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;stream buffer&lt;/em&gt; is a memory buffer for the stream - the &lt;code class=&quot;highlighter-rouge&quot;&gt;streambuf&lt;/code&gt; is an interface that defines a mapping from a stream to a device, file or memory.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The stream is responsible for converting data into an appropriate format.&lt;/li&gt;
  &lt;li&gt;The streambuf actually communicates the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.comi/csknk/file-input-object&quot;&gt;GitHub repo with working example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/fstream/fstream/&quot;&gt;fstream&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3&quot;&gt;Controlling terminal: &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/tty&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3&quot;&gt;Stream Buffers&lt;/a&gt;: YouTube, Bo Qian&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.learncpp.com/cpp-tutorial/183-output-with-ostream-and-ios/&quot;&gt;Output with ostream &amp;amp; ios&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 12 Sep 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/09/Construct-C++-Objects-From-Stdin/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/09/Construct-C++-Objects-From-Stdin/</guid>
      </item>
      
    
      
      <item>
        <title>Diffie Hellman Key Exchange</title>
        <description>&lt;p&gt;The fastest encryption schemes are symmetric - both participants have a copy of a secret key, which is used to encrypt and decrypt messages.&lt;/p&gt;

&lt;p&gt;In order to set up such a scheme, Alice and Bob would need to share the secret key by means of a secure channel - and this is where symmetric encryption schemes can be problematic.&lt;/p&gt;

&lt;p&gt;If Alice and Bob have a secure communication channel by which to transfer a secret key, it obviates to some extent the necessity for symmetric encryption - they could simply exchange their private message over the secret channel. If they don’t have a secure communication channel, they can’t securely exchange a private key and symmetric encryption is therefore not possible.&lt;/p&gt;

&lt;p&gt;Diffie Hellman Key Exchange allows participants to independently compute a shared secret key such that it is computationally infeasible for an adversary to determine the key. Once the “secret” key has been computed by the participants, they can communicate using symmetric encryption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Neither participant chooses the secret key - but by the end of the algorithm, they each share a copy.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;algortihm&quot;&gt;Algortihm&lt;/h2&gt;
&lt;h3 id=&quot;shared-values-public&quot;&gt;Shared Values (Public)&lt;/h3&gt;
&lt;p&gt;Participants Alice and Bob agree on two shared values, q and g.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;q: A large prime number.&lt;/li&gt;
  &lt;li&gt;g: Primitive root of q.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These values are public - they are available to any potential adverary.&lt;/p&gt;

&lt;h3 id=&quot;private-secret-keys&quot;&gt;Private (Secret) Keys&lt;/h3&gt;
&lt;p&gt;Alice and Bob each selects a large random number &lt;em&gt;X&lt;/em&gt; that serves as their individual private key.&lt;/p&gt;

&lt;p&gt;They do not share their private keys - the security of the system is dependent upon these values remaining secret.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Alice’s private key: &lt;em&gt;Xa&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Bob’s private key: &lt;em&gt;Xb&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;public-keys&quot;&gt;Public Keys&lt;/h3&gt;
&lt;p&gt;Each particpant computes their Public key by raising &lt;em&gt;g&lt;/em&gt; to the power of their private key, modulo q:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Y&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;X&lt;/sup&gt;&lt;/em&gt; modulo &lt;em&gt;q&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Alice’s public key: &lt;em&gt;Ya&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xa&lt;/sup&gt;&lt;/em&gt; modulo &lt;em&gt;q&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Bob’s public key: &lt;em&gt;Yb&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xb&lt;/sup&gt;&lt;/em&gt; modulo &lt;em&gt;q&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These public keys are then shared. Public sharing of these keys does not affect the security of the system.&lt;/p&gt;

&lt;h3 id=&quot;compute-shared-key&quot;&gt;Compute Shared Key&lt;/h3&gt;
&lt;p&gt;Each participant computes a shared private key by raising the other participant’s Public key to the power of their own Private key.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This results in each participant having the same secret key - but computation of the secret key is not computationally feasible without the particpant’s Private key that they used to generate the Public key.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;summary-of-values&quot;&gt;Summary of Values&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Value&lt;/th&gt;
      &lt;th&gt;Alice&lt;/th&gt;
      &lt;th&gt;Bob&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Random number: private&lt;/td&gt;
      &lt;td&gt;Xa&lt;/td&gt;
      &lt;td&gt;Xb&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Computed public key&lt;/td&gt;
      &lt;td&gt;Ya = g&lt;sup&gt;Xa&lt;/sup&gt; mod q&lt;/td&gt;
      &lt;td&gt;Yb = g&lt;sup&gt;Xb&lt;/sup&gt; mod q&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Keys swapped&lt;/td&gt;
      &lt;td&gt;Ya, Yb&lt;/td&gt;
      &lt;td&gt;Yb, Ya&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Computed shared key&lt;/td&gt;
      &lt;td&gt;K&lt;sub&gt;ab&lt;/sub&gt; = Yb&lt;sup&gt;Xa&lt;/sup&gt;&lt;/td&gt;
      &lt;td&gt;K&lt;sub&gt;ba&lt;/sub&gt; = Ya&lt;sup&gt;Xb&lt;/sup&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ya&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xa&lt;/sup&gt;&lt;/em&gt; mod &lt;em&gt;q&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yb&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xb&lt;/sup&gt;&lt;/em&gt; mod &lt;em&gt;q&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Alice:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(g&lt;sup&gt;Xb&lt;/sup&gt;)&lt;sup&gt;Xa&lt;/sup&gt;&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xb . Xa&lt;/sup&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Bob:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(g&lt;sup&gt;Xa&lt;/sup&gt;)&lt;sup&gt;Xb&lt;/sup&gt;&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xa . Xb&lt;/sup&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This works because powers of powers are commutative:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(a&lt;sup&gt;b&lt;/sup&gt;)&lt;sup&gt;c&lt;/sup&gt;&lt;/em&gt; = &lt;em&gt;a&lt;sup&gt;bc&lt;/sup&gt;&lt;/em&gt; = &lt;em&gt;a&lt;sup&gt;cb&lt;/sup&gt;&lt;/em&gt; = &lt;em&gt;(a&lt;sup&gt;c&lt;/sup&gt;)&lt;sup&gt;b&lt;/sup&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;summary-of-the-private--exchanged-values&quot;&gt;Summary of the Private &amp;amp; Exchanged Values&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Participant&lt;/th&gt;
      &lt;th&gt;Private Key&lt;/th&gt;
      &lt;th&gt;Shared Public Key&lt;/th&gt;
      &lt;th&gt;Shared Key: computed individually&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Alice&lt;/td&gt;
      &lt;td&gt;Xa&lt;/td&gt;
      &lt;td&gt;g&lt;sup&gt;Xa&lt;/sup&gt; mod q&lt;/td&gt;
      &lt;td&gt;g&lt;sup&gt;Xb . Xa&lt;/sup&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Bob&lt;/td&gt;
      &lt;td&gt;Xb&lt;/td&gt;
      &lt;td&gt;g&lt;sup&gt;Xb&lt;/sup&gt; mod q&lt;/td&gt;
      &lt;td&gt;g&lt;sup&gt;Xa . Xb&lt;/sup&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Alice and Bob now share a key that is known uniquely to themselves.&lt;/p&gt;

&lt;p&gt;They each used their individual private key along with the other participants “public” key.&lt;/p&gt;

&lt;p&gt;So long as the public keys are computed with the same values of g and q, the key that they each compute independently will be identical.&lt;/p&gt;

&lt;h2 id=&quot;security-discrete-logarithm-problem&quot;&gt;Security: Discrete Logarithm Problem&lt;/h2&gt;
&lt;p&gt;It is hard to compute the private key from the public key.&lt;/p&gt;

&lt;p&gt;For example, given Alice’s public key (&lt;em&gt;Ya&lt;/em&gt; = &lt;em&gt;g&lt;sup&gt;Xa&lt;/sup&gt;&lt;/em&gt; mod &lt;em&gt;q&lt;/em&gt;), it is hard to determine the private key Xa from g&lt;sup&gt;Xa&lt;/sup&gt;. This is known as the &lt;strong&gt;discrete logarithm problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Given &lt;em&gt;g&lt;sup&gt;e&lt;/sup&gt;&lt;/em&gt; ≡ &lt;em&gt;c&lt;/em&gt; mod &lt;em&gt;q&lt;/em&gt;, it is difficult to compute &lt;em&gt;e&lt;/em&gt; when &lt;em&gt;g&lt;/em&gt; (the original generator), &lt;em&gt;c&lt;/em&gt;(a public key) and &lt;em&gt;q&lt;/em&gt; (the modulus) are known.&lt;/p&gt;
</description>
        <pubDate>Tue, 18 Aug 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/08/Diffie-Hellman-Key-Exchange/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/08/Diffie-Hellman-Key-Exchange/</guid>
      </item>
      
    
      
      <item>
        <title>Pattern Matching in Rust During Variable Assignment</title>
        <description>&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;match&lt;/code&gt; keyword in Rust is something like a C &lt;code class=&quot;highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement - but it can also be used during variable assignment:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c&quot;&gt;// Match is an expression as well as a statement. This example shows how&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// a variable is set based on an Option enum.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// ------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++MELON MELON MELON+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// Some variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                        &lt;span class=&quot;c&quot;&gt;// None variant&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// The variable msg is assigned a value dependent upon the Option variant	&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// m is the unwrapped data from the option &lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Out of Cheese Error&quot;&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// As above, but handling the None variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// In this case we won't enter this branch&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Out of Cheese Error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// msg_2 set to this value&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg_2 = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&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;c&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg = +++MELON MELON MELON+++&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg_2 = Out of Cheese Error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is a really handy idiom given that functions in Rust often return an &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; enum.&lt;/p&gt;

&lt;p&gt;You could achieve the same thing using &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap_or()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++MELON MELON MELON+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// Some variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                        &lt;span class=&quot;c&quot;&gt;// None variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default_msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+++Please Reinstall Universe and Reboot+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;default_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// As above, but handling the None variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;default_msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg_2 = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&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;c&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg = +++MELON MELON MELON+++&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg_2 = +++Please Reinstall Universe and Reboot+++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 02 Jul 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/07/Pattern-Matching-in-Rust-During-Variable-Assignment/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/07/Pattern-Matching-in-Rust-During-Variable-Assignment/</guid>
      </item>
      
    
      
      <item>
        <title>Using C++ Vectors in C Functions</title>
        <description>&lt;p&gt;You can use C utilities in C++ code. For example, you may be using openssl to perform hashing algorithms.&lt;/p&gt;

&lt;p&gt;In this case, the openssl code is C rather than C++. It can’t operate on vectors of bytes - instead it uses basic C style data structures like &lt;code class=&quot;highlighter-rouge&quot;&gt;const void *&lt;/code&gt; - an array of void pointers.&lt;/p&gt;

&lt;h2 id=&quot;example-sha256update&quot;&gt;Example: &lt;code class=&quot;highlighter-rouge&quot;&gt;SHA256_update()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;SHA256_update()&lt;/code&gt; function is part of the openssl library. The signature of this function is: &lt;code class=&quot;highlighter-rouge&quot;&gt;int SHA256_Update(SHA256_CTX *c, const void *preimageBytes, size_t len);&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It serves to fill the bytes of &lt;code class=&quot;highlighter-rouge&quot;&gt;c&lt;/code&gt; with the hash of &lt;code class=&quot;highlighter-rouge&quot;&gt;preimageBytes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that 2nd parameter is a &lt;code class=&quot;highlighter-rouge&quot;&gt;const void *&lt;/code&gt;. This means that the caller must provide a pointer to data rather than a &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; or a vector iterator.&lt;/p&gt;

&lt;p&gt;The caller can either pass &lt;code class=&quot;highlighter-rouge&quot;&gt;v.data()&lt;/code&gt; or a pointer to the first element in the vector: &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;v[0]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;code-example&quot;&gt;Code Example&lt;/h2&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// main.cpp
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;iomanip&amp;gt;
#include &amp;lt;openssl/sha.h&amp;gt;
#include &amp;lt;openssl/ripemd.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define HASH_LEN 32
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preimageBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&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;n&quot;&gt;SHA256_CTX&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;SHA256_Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;SHA256_Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preimageBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SHA256_Final&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preimageBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xbe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HASH_LEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sha256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preimageBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preimageBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;'0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To compile:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;g++ -W -Wall -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;c++17 -g -o prog main.cpp -lssl -lcrypto
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 28 Jun 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/06/Using-C++-Vectors-in-C-Functions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/06/Using-C++-Vectors-in-C-Functions/</guid>
      </item>
      
    
      
      <item>
        <title>Pseudo Random Numbers in a Range and Modulo Bias</title>
        <description>&lt;p&gt;It is sometimes necessary to obtain a pseudo-random number from a specific range. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Simulating a fair die roll, where the value should be between 1 and 6 inclusive&lt;/li&gt;
  &lt;li&gt;Randomly selecting a word from a word list - for example, generating a secure passphrase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be achieved by using modular arithmetic whereby numbers are limited to a certain range, wrapping around when the range is exceeded.&lt;/p&gt;

&lt;h2 id=&quot;selecting-from-a-range&quot;&gt;Selecting From a Range&lt;/h2&gt;
&lt;p&gt;Suppose you have a random number generator that generates numbers with a sufficient degree of randomness in the range [0, 16) - i.e. 16 integers, from 0 to 15 inclusive.&lt;/p&gt;

&lt;p&gt;You need a random number in the range [1, 6].&lt;/p&gt;

&lt;p&gt;To achieve this, you could reduce the range of the random number by modular division:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Determine an appropriate modulus, &lt;em&gt;m&lt;/em&gt; such that &lt;em&gt;m&lt;/em&gt; = &lt;em&gt;upper bound&lt;/em&gt; - &lt;em&gt;lower bound&lt;/em&gt; + 1 (in this case, 6 - 1 + 1 = 6)&lt;/li&gt;
  &lt;li&gt;Compute the remainder (mod &lt;em&gt;m&lt;/em&gt;) of the random number returned&lt;/li&gt;
  &lt;li&gt;Add this to the lower bound (in this case, 1) to get a random number in the required range&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The diagram below shows each possible random number in our 16 number range in black, with the remainder mod 6 shown in blue:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/generated/16-grid-200x200-ab2aed.png&quot; class=&quot;img-responsive&quot; title=&quot;Representation of 16 possible random numbers showing Modulo bias&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From this diagram, you can see that the probability of returning a number of 1 to 6 is NOT evenly distributed. You can easily see probabilities in this case by simply counting how many times they occur and dividing by the total number of possible values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Mod 6 Value + 1, Random Number 0-15&lt;/th&gt;
      &lt;th&gt;Probability&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;3/16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;3/16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;3/16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;3/16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;2/16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;2/16&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In this case the values 5 and 6 have a (slightly) lower probability of being returned, even if the original random number (between 0 and 15) is truly random. This effect is known as &lt;strong&gt;modulo bias&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;random-bytes&quot;&gt;Random Bytes&lt;/h2&gt;
&lt;p&gt;Modern computers operate effectively at the level of the byte (8 bits) - under Linux, you might get a pseudo-random number by fetching a byte from the &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/urandom&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/random&lt;/code&gt; devices - these are basically the Linux kernel API for accessing randomness.&lt;/p&gt;

&lt;p&gt;This random byte represents a decimal number between 0 (an empty byte) and 255 (wherein all bits are set).&lt;/p&gt;

&lt;p&gt;To continue with the fair die analogy, consider how we might return a number in the range [1, 6] for all possible values of a single byte:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/generated/byte-grid-768x768-5f4089.png&quot; class=&quot;img-responsive&quot; title=&quot;Representation of possible Byte numeric values showing Modulo bias&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This time the absolute difference in probabilities is smaller, because the possible range for our original random number is greater - there are 256 possibilities compared to 16:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Mod 6 Value + 1, Random Number 0-255&lt;/th&gt;
      &lt;th&gt;Probability&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;43/256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;43/256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;43/256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;43/256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;42/256&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;42/256&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;correcting-for-modulo-bias&quot;&gt;Correcting for Modulo Bias&lt;/h2&gt;
&lt;p&gt;We can correct modulo bias by discarding any random number in excess of the maximum exact multiple of our modulus.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Determine the modulus &lt;em&gt;m&lt;/em&gt; such that we return numbers in the required range [&lt;em&gt;lower bound&lt;/em&gt;, &lt;em&gt;upper bound&lt;/em&gt;]: &lt;em&gt;upper bound&lt;/em&gt; - &lt;em&gt;lower bound&lt;/em&gt; + &lt;em&gt;lower bound&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Take the number of possible random values - this will be the maximum possible value + 1 to account for the possibility of zero&lt;/li&gt;
  &lt;li&gt;Determine the remainder of dividing the number of possible random numbers by &lt;em&gt;m&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Subtract this &lt;em&gt;excess&lt;/em&gt; from the maximum possible random number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a threshold above which we discard random numbers. If the random number exceeds this threshold, we re-roll our random number generator until we return a value that is within the range. This ensures that the final results are evenly distributed.&lt;/p&gt;

&lt;p&gt;Taking the 16 value example above, we would discard random values greater than or equal to 12:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;16 (mod 6) ≡ 4&lt;/li&gt;
  &lt;li&gt;16 - 4 = 12&lt;/li&gt;
  &lt;li&gt;If the random integer is &amp;gt; 11 we should reject it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing the same thing for the one-byte example, 251 is our threshold above which we should reject values.&lt;/p&gt;

&lt;h2 id=&quot;example-python&quot;&gt;Example: Python&lt;/h2&gt;
&lt;p&gt;This example uses the range-restricted random number to pseudo-randomly select a word from a wordlist:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;subprocess&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;check_output&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RandomInRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    Class that provides a pseudo-random number within a given range,
    corrected for modulo bias.
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_src_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/dev/urandom'&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set_parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;max_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;c&quot;&gt;# Max required random number is 2⁸ - 1&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;2&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;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;c&quot;&gt;# Max required random number is 2¹⁶ - 1&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;3&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;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;c&quot;&gt;# Max required random number is 2²⁴ - 1&lt;/span&gt;
            &lt;span class=&quot;mi&quot;&gt;4&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;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Max required random number is 2³² - 1&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;c&quot;&gt;# Compute modulus m that will be used to restrict range&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Max value exceeded.&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AssertionError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The range magnitude {} is too large.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&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;c&quot;&gt;# Determine number of pseudo random bytes needed and the related max random value&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&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;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
                &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
                &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;excess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_allowed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;excess&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;random_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;big&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RandomWords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    Class that builds a list of randomly-selected words.
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Number of words&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Initialise an empty list for the randomly selected words&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# The word list to select from (Ubuntu/Debian)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/usr/share/dict/cracklib-small'&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Number of lines in the wordlist file&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyspace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sum&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Initialise a RandomInRange object&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomInRange&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;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;make_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        Randomly select words from a wordlist and append them to a list.
        Uses a modular range-reduced random number to make the selection
        without modulo bias.
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&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;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;r_num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_words&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_one_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'utf-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_one_line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        sed is a reasonable way to get a line from a file indexed by line number.
        If there is a more Pythonic way of doing this, please leave a comment.
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;check_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;sed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;-n&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;sp&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomWords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;example-bash&quot;&gt;Example: Bash&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Copyright 2020 David Egan&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# you may not use this file except in compliance with the License.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You may obtain a copy of the License at&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# http:#www.apache.org/licenses/LICENSE-2.0&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Random Number Within a Specific Range&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# To obtain a random number within a particular (inclusive) range within a Bash script:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# * Source this file&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# * Run `random_number_in_range &amp;lt;lower bound&amp;gt; &amp;lt;upper bound&amp;gt;`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# * The `$random_number` variable in your calling script will have an&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# appropriate random number&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# If you run `random_number_in_range` with no parameters, you will be prompted to enter&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# a lower and upper value.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# -----------------------------------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;RANDOM_SOURCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/dev/urandom&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;ONE_BYTE_MAX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; « &lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TWO_BYTE_MAX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; « &lt;span class=&quot;m&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;THREE_BYTE_MAX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; « &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;set_n_bytes &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lower&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;lt; &lt;span class=&quot;nv&quot;&gt;$ONE_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;n_random_bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1
		&lt;span class=&quot;nv&quot;&gt;max_random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ONE_BYTE_MAX&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;gt; &lt;span class=&quot;nv&quot;&gt;$ONE_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;lt; &lt;span class=&quot;nv&quot;&gt;$TWO_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;n_random_bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2
		&lt;span class=&quot;nv&quot;&gt;max_random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TWO_BYTE_MAX&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;gt; &lt;span class=&quot;nv&quot;&gt;$TWO_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;lt; &lt;span class=&quot;nv&quot;&gt;$THREE_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;n_random_bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3
		&lt;span class=&quot;nv&quot;&gt;max_random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$THREE_BYTE_MAX&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$m&lt;/span&gt; &amp;gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$THREE_BYTE_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Too big for this script&quot;&lt;/span&gt;
		&lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
	&lt;span class=&quot;k&quot;&gt;fi

	&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lower&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;excess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$max_random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;max_allowed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$max_random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$excess&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;random_in_range &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$excess&lt;/span&gt; !&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; 1 &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;do
			&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;random_number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;od -N&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;n_random_bytes&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; -An -i &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;RANDOM_SOURCE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;})&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$random_number&lt;/span&gt; &amp;lt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$max_allowed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
				&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;break
			&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi
		done
	else
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;random_number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;od -N&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;n_random_bytes&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; -An -i &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;RANDOM_SOURCE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;})&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;fi
	&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;random_number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$random_number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lower&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;set_inputs &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;-eq 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Enter lower (inclusive) bound:&quot;&lt;/span&gt;
		&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;lower
		&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Enter upper (inclusive) bound:&quot;&lt;/span&gt;
		&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;upper
	&lt;span class=&quot;k&quot;&gt;else
		&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;fi
	&lt;/span&gt;set_n_bytes &lt;span class=&quot;nv&quot;&gt;$lower&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$upper&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;random_number_in_range &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	set_inputs &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
	random_in_range
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;test_run &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	. tests
	set_inputs 1 6
	test_diceroll
	set_inputs 1 4
	test_4_sided_diceroll
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;test&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; test_run
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If you copy and paste the above code it will error - I used digraphs for the left-shift operators because markdown syntax highlighting thinks &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; should start a heredoc, even inside a &lt;code class=&quot;highlighter-rouge&quot;&gt;$(( ))&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;If you want a copy of this script you can &lt;a href=&quot;https://raw.githubusercontent.com/csknk/bash-random-words/master/random.sh&quot;&gt;get it here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-randomness&quot;&gt;A Note on Randomness&lt;/h2&gt;
&lt;p&gt;Remember that your source of “Randomness” is very important. For most purposes, we can use Pseudo random number generators such as &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/urandom&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/random&lt;/code&gt; on Linux.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. For, as has been pointed out several times, there is no such thing as a random number — there are only methods to produce random numbers, and a strict arithmetic procedure of course is not such a method.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://en.wikiquote.org/wiki/John_von_Neumann&quot;&gt;John Von Neumann&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because computers are deterministic, they can only ever produce pseudo-randomness.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/bash-random-words&quot;&gt;GitHub repo&lt;/a&gt; for this post with examples using Bash and Python to generate randomly selected words&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/linux-randomness-cpp/blob/master/examples/diceroll.cpp&quot;&gt;Randomness in C++&lt;/a&gt; - I included a “diceroll” example here that simulates a diceroll using C++ and the Linux kernel randomness API&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/&quot;&gt;Fast alternative to modulo reduction&lt;/a&gt; - if speed is important for your application, read this article!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Image by &lt;a href=&quot;https://pixabay.com/users/955169-955169/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1502706&quot;&gt;955169&lt;/a&gt; from &lt;a href=&quot;https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=1502706&quot;&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Mon, 08 Jun 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/06/Pseudo-Random-Numbers-in-a-Range-and-Modulo-Bias/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/06/Pseudo-Random-Numbers-in-a-Range-and-Modulo-Bias/</guid>
      </item>
      
    
      
      <item>
        <title>Notes on GNU Make</title>
        <description>&lt;p&gt;The GNU &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; utility is a tool that maintains groups of programmes &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; can determine which pieces of a large programme need to be compiled and/or recompiled, and generally take care of compilation and recompilation in an efficient way.&lt;/p&gt;

&lt;p&gt;You can use &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; with any programming language whose compiler can be run from the command line. Beyond compiling programmes, &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; can describe any task that involves updating files automatically when other files change.&lt;/p&gt;

&lt;h2 id=&quot;the-makefile&quot;&gt;The Makefile&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; is used to describe relationships between files in the programme, and the commands necessary for updating files.&lt;/p&gt;

&lt;p&gt;In C programmes, the executable file is updated (“linked”) from “object” files, which are in turn made by compiling source files.&lt;/p&gt;

&lt;p&gt;Once you’ve written a suitable &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt;, you just need to run &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; in the programme root directory to perform all necessary recompilations.&lt;/p&gt;

&lt;p&gt;If you don’t specify a &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;make -f &amp;lt;makefile&amp;gt;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; will look for the makefiles:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;GNUmakefile&lt;/li&gt;
  &lt;li&gt;makefile&lt;/li&gt;
  &lt;li&gt;Makefile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;in that order. It is recommended to call the makefile &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The makefile contains one or more rules that specify how a target is produced from prerequisite files. &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; updates a target if the prerequisite files that it depends upon have been modified since the target was last changed, or if the target does not exist.&lt;/p&gt;

&lt;h2 id=&quot;rules&quot;&gt;Rules&lt;/h2&gt;
&lt;p&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; rule is comprised of a target specification and it’s prerequisite files, all on one line and with the target separated from the prerequisites by a colon.&lt;/p&gt;

&lt;p&gt;After the space-separated list of prerequisites, the rule has a newline and a list of commands that should be executed required to rebuild the target from the prerequisites.&lt;/p&gt;

&lt;p&gt;Commands may be added over multiple lines, but each line that contains a command must start with a TAB character.&lt;/p&gt;

&lt;h3 id=&quot;example-makefile&quot;&gt;Example Makefile&lt;/h3&gt;

&lt;p&gt;The following makefile has 3 targets: &lt;code class=&quot;highlighter-rouge&quot;&gt;myProgramme&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;moduleOne&lt;/code&gt; &amp;amp; &lt;code class=&quot;highlighter-rouge&quot;&gt;moduleTwo&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;myProgramme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;moduleOne.o moduleTwo.o&lt;/span&gt;
	gcc -o myProgramme moduleOne.o moduleTwo.o

&lt;span class=&quot;nl&quot;&gt;moduleOne.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;moduleOne.c moduleOne.h standaloneHeader.h&lt;/span&gt;
	gcc -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gnu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;gnu99 -pedantic -Wall -c moduleOne.c

&lt;span class=&quot;nl&quot;&gt;moduleTwo.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;moduleTwo.c moduleTwo.h standaloneHeader.h&lt;/span&gt;
	gcc -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gnu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;gnu99 -pedantic -Wall -c moduleTwo.c
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;special-make-variables&quot;&gt;Special Make Variables&lt;/h2&gt;
&lt;p&gt;Inside an action, special variables are available for matching filenames:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$@&lt;/code&gt;: The full target name of the current target&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$?&lt;/code&gt;: Dependencies that are &lt;em&gt;newer&lt;/em&gt; than the current target&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$*&lt;/code&gt;: Returns text corresponding to &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; in current target&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$&amp;lt;&lt;/code&gt;: Returns the name of the first dependency&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$^&lt;/code&gt;: Name of all dependencies, space separated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows your makefile to be more concise:&lt;/p&gt;

&lt;h3 id=&quot;example-makefile-2&quot;&gt;Example Makefile 2&lt;/h3&gt;

&lt;p&gt;Example C++ makefile for the following project structure:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;main.cpp&lt;/code&gt;: includes grade.h &amp;amp; util.h&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;util.cpp&lt;/code&gt;: includes util.h&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;util.h&lt;/code&gt;: contains declarations&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grade.cpp&lt;/code&gt;: includes grade.h&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grade.h&lt;/code&gt;: contains declarations&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Set a variable for flags to avoid repetition
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; -W -Wall -pedantic -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;c++17 -g
&lt;span class=&quot;nv&quot;&gt;CXX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; g++ &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; grades

&lt;span class=&quot;c&quot;&gt;# The target has the dependencies util.o, main.o &amp;amp; grade.o
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;$(NAME)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;util.o main.o grade.o&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;$(CXX)&lt;/span&gt; -o &lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$^&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# For any .c file, build an object file by applying the actions on the following line.
# This is a pattern rule, a type of implicit rule. Specifies one target and one dependency.
# Causes one invocation of $(CXX) for each target.
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;%.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;%.c&lt;/span&gt;
	&lt;span class=&quot;nv&quot;&gt;$(CXX)&lt;/span&gt; -c &lt;span class=&quot;nv&quot;&gt;$&amp;lt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# util.c and grade.c include header files. Their object files are generated by the implicit
# rule above, but the following lines specify additional dependencies:
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;util.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;util.h&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;grade.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;grade.h&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Remove the executable and all object files
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;.PHONY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;clean&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;clean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;rm &lt;span class=&quot;nv&quot;&gt;$(NAME)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.o
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that the pattern rule (&lt;code class=&quot;highlighter-rouge&quot;&gt;%.o: %.c&lt;/code&gt;) involves matching file names - the &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; can match any non-empty substring, whereas the characters match only themselves. The rule says: “Compile .c files into corresponding .o files”.&lt;/p&gt;

&lt;p&gt;In this example, &lt;code class=&quot;highlighter-rouge&quot;&gt;main.o&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;util.o&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;grade.o&lt;/code&gt; will be made from &lt;code class=&quot;highlighter-rouge&quot;&gt;main.c&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;util.c&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;grade.c&lt;/code&gt; respectively.&lt;/p&gt;

&lt;h2 id=&quot;variables-for-implicit-rules&quot;&gt;Variables for Implicit Rules&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt;: Extra flags to give to the C compiler.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CPPFLAGS&lt;/code&gt;: Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CXX&lt;/code&gt;: Program for compiling C++ programs, default &lt;code class=&quot;highlighter-rouge&quot;&gt;g++&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CXXFLAGS&lt;/code&gt;: Extra flags to give to the C++ compiler.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;set-variables&quot;&gt;Set Variables&lt;/h2&gt;
&lt;p&gt;Assign variables within a Makefile.&lt;/p&gt;

&lt;p&gt;In a Makefile, a variable is a name assigned to a value, which is a string of text. Values are substituted into targets, prerequisites, commands etc.&lt;/p&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Set a variable to hold the absolute path of the Makefile
# Getting `firstword` strips off any includes
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ABS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;dir &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;realpath &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;firstword &lt;span class=&quot;nv&quot;&gt;$(MAKEFILE_LIST)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Alternatively:
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ABS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;shell&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;See &lt;a href=&quot;https://timmurphy.org/2015/09/27/how-to-get-a-makefile-directory-path/&quot;&gt;this article&lt;/a&gt; for a more complete description.&lt;/p&gt;

&lt;p&gt;Variables can be either recursively expanded (defined using the &lt;code class=&quot;highlighter-rouge&quot;&gt;=&lt;/code&gt; operator) or simply expanded (defined using the &lt;code class=&quot;highlighter-rouge&quot;&gt;:=&lt;/code&gt; operator).&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;http://make.mad-scientist.net/evaluation-and-expansion/&quot;&gt;this article&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h2 id=&quot;example-c&quot;&gt;Example: C&lt;/h2&gt;
&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Set common parameters
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; gcc
&lt;span class=&quot;nv&quot;&gt;CFLAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;gnu99 -W -Wall -pedantic -g

&lt;span class=&quot;c&quot;&gt;# Specify necessary targets/tasks
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;maxSeq.o test-subseq.o test-subseq&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Compile maxSeq.c into maxSeq.o
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;maxSeq.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;maxSeq.c&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$(CC)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$(CFLAGS)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;maxSeq.c&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Compile test-subseq.c into test-subseq.o
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;test-subseq.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test-subseq.c&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$(CC)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$(CFLAGS)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;test-subseq.c&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Link object files test-subseq.o and maxSeq.o into an executable test-subseq
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;test-subseq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test-subseq.o maxSeq.o&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;$(CC)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$(CFLAGS)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;test-subseq&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;test-subseq.o&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;maxSeq.o&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;clean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;maxSeq.o&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;test-subseq.o&lt;/span&gt;

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

&lt;h2 id=&quot;example-c-makefile-to-create-multiple-executables&quot;&gt;Example: C++ Makefile to Create Multiple Executables&lt;/h2&gt;
&lt;p&gt;In this example, each &lt;code class=&quot;highlighter-rouge&quot;&gt;*.cpp&lt;/code&gt; file is compiled and linked into a distinct executable:&lt;/p&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Makefile to compile and link all C++ files in the current directory, such that each C++
# file results in a unique executable.
#
# This is useful for experimentation, testing and small-scale projects.
# 
# Copyright (c) David Egan 2020
# SPDX-License-Identifier: GPL-2.0-or-later
&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;WARNINGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; -pedantic -Wall -Wfatal-errors -Wextra -Wno-unused-parameter -Wno-unused-variable
&lt;span class=&quot;nv&quot;&gt;BIN_DIR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; bin
&lt;span class=&quot;nv&quot;&gt;OBJS_DIR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$(BIN_DIR)&lt;/span&gt;/objs
&lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$(WARNINGS)&lt;/span&gt; -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;c++17 -g
&lt;span class=&quot;nv&quot;&gt;LDFLAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;CXX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; g++ &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CXXFLAGS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Handle all .cpp files together - allows more to be added to the project without
# changing the Makefile
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SRCS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;wildcard &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.cpp&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# String substitution to generate appropriate names for executable files
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;EXECUTABLE_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;SRCS:%.cpp&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(BIN_DIR)&lt;/span&gt;/%&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Note that the following is an alternative way of performing string substitution:
# EXECUTABLE_FILES = $(patsubst %.cpp,$(BIN_DIR)/%,$(SRCS))
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Output for debugging purposes
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$(info&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;EXECUTABLE_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(EXECUTABLE_FILES)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# There should be a corresponding object file for each .cpp file
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OBJECT_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;SRCS:%.cpp&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(OBJS_DIR)&lt;/span&gt;/%.o&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;.PHONY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;all clean&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$(EXECUTABLE_FILES)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# This pattern is triggered by the `all` rule. This is a builtin rule
# that builds executables from object files.
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;$(BIN_DIR)/%&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$(OBJS_DIR)/%.o&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(CXX)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$(LDFLAGS)&lt;/span&gt; -o &lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$^&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Builtin rule to generate object files from .cpp files
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;$(OBJS_DIR)/%.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;%.cpp&lt;/span&gt;
	&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;info Building object file &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(&amp;lt;)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;mkdir -p &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;@D&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(CXX)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$(CXXFLAGS)&lt;/span&gt; -o &lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt; -c &lt;span class=&quot;nv&quot;&gt;$&amp;lt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Additional dependencies
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;$(OBJS_DIR)/selection-sort.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;util.h&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;$(OBJS_DIR)/merge-sort.o&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;util.h&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;clean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
	rm &lt;span class=&quot;nv&quot;&gt;$(OBJS_DIR)&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.o
	rm -f &lt;span class=&quot;nv&quot;&gt;$(BIN_DIR)&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Project Structure:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
.
├── bin
│   ├── merge-sort
│   ├── objs
│   │   ├── merge-sort.o
│   │   └── selection-sort.o
│   └── selection-sort
├── Makefile
├── merge-sort.cpp
├── selection-sort.cpp
└── util.h

2 directories, 8 files
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;output-variables&quot;&gt;Output Variables&lt;/h2&gt;
&lt;p&gt;The internal &lt;code class=&quot;highlighter-rouge&quot;&gt;info&lt;/code&gt; function allows you to output variables to stdout:&lt;/p&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$(info&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;EXECUTABLE_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(EXECUTABLE_FILES)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# outputs the value of `EXECUTABLE_FILES`
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;string-substitution&quot;&gt;String Substitution&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$(patsubst pattern,replacement,text)&lt;/code&gt; finds whitespace separated words in &lt;code class=&quot;highlighter-rouge&quot;&gt;text&lt;/code&gt; that match &lt;code class=&quot;highlighter-rouge&quot;&gt;pattern&lt;/code&gt; and replace these with &lt;code class=&quot;highlighter-rouge&quot;&gt;replacement&lt;/code&gt;. The pattern may contain a &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; character, which acts as a wildcard matching any number of characters within a word - escape literal % characters in a pattern with a &lt;code class=&quot;highlighter-rouge&quot;&gt;\&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# For each &quot;word&quot; in $(SRCS) remove .cpp and prepend a directory path
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;EXECUTABLE_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;patsubst %.cpp,&lt;span class=&quot;nv&quot;&gt;$(BIN_DIR)&lt;/span&gt;/%,&lt;span class=&quot;nv&quot;&gt;$(SRCS)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can use &lt;a href=&quot;https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html#SEC61&quot;&gt;substitution references&lt;/a&gt; to get the same effect:&lt;/p&gt;
&lt;div class=&quot;language-make highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;EXECUTABLE_FILES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;SRCS:%.cpp&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$(BIN_DIR)&lt;/span&gt;/%&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Substitution references substitute the value of a variable with the specified alterations, in the form:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$(VAR:a=b)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means take the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;VAR&lt;/code&gt; and replace every &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; at the end of a word with &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;. Wildcards can also be used, as shown in the example above.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html&quot;&gt;Pattern Rules&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cl.cam.ac.uk/teaching/0910/UnixTools/make.pdf&quot;&gt;Gnu Make book&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cs.colostate.edu/~cs157/LectureMakefile.pdf&quot;&gt;Makefile lecture&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cprogramming.com/tutorial/makefiles.html&quot;&gt;Makefile tutorial, cprogramming.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://makefiletutorial.com/&quot;&gt;Makefile tutorial&lt;/a&gt;, makefiletutorial.com&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html#SEC61&quot;&gt;Substitution References&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_8.html#SEC77&quot;&gt;String Substitution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 04 Jun 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/06/Notes-on-GNU-Make/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/06/Notes-on-GNU-Make/</guid>
      </item>
      
    
      
      <item>
        <title>Set Default Values in Rust</title>
        <description>&lt;p&gt;Rust provides many ways to set a default value - or to fallback gracefully in the event of an error. This article focuses on how to handle &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; types.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; type represents an optional value. An &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; can either contain &lt;code class=&quot;highlighter-rouge&quot;&gt;Some()&lt;/code&gt; value, or &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; (which is self-explanatory). Specifically, &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; is an enum with two variants:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt;: indicating lack of value or failure&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Some(value)&lt;/code&gt;: A tuple struct that wraps a value of type &lt;code class=&quot;highlighter-rouge&quot;&gt;T&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;unwrapping-an-option&quot;&gt;Unwrapping an Option&lt;/h2&gt;
&lt;p&gt;If the &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; is a &lt;code class=&quot;highlighter-rouge&quot;&gt;Some&lt;/code&gt; variant, the value can be accessed using the &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap()&lt;/code&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x unwraps to give the value {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// x unwraps to give the value 42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Trying to &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap()&lt;/code&gt; a &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; variant causes a &lt;code class=&quot;highlighter-rouge&quot;&gt;panic!&lt;/code&gt;, which is not a particulary elegant way of terminating early:&lt;/p&gt;
&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;unwrapping y will cause a panic! {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; 
&lt;span class=&quot;c&quot;&gt;// thread 'main' panicked at 'called `Option::unwrap()` on a `None` value'...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;unwrap-or&quot;&gt;Unwrap, Or?&lt;/h2&gt;
&lt;p&gt;If you use the &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap_or()&lt;/code&gt; method to unwrap an &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, you get to specify a fallback/default value.&lt;/p&gt;

&lt;p&gt;This ensures that the programme does not panic and is useful if the &lt;em&gt;only&lt;/em&gt; appropriate response to the &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; variant is a default value:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c&quot;&gt;// Simulate function returning Option&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;	&lt;span class=&quot;c&quot;&gt;// Some variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;			&lt;span class=&quot;c&quot;&gt;// None variant&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;c&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// a = 42&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// b = 13&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Another example that uses &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;&amp;amp;'static str&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c&quot;&gt;// Simulate function returning Option of Some() variant:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++MELON MELON MELON+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// Simulate function returning Option of None variant:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;empty_message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;empty_message&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap_or&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;c&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// a = +++MELON MELON MELON+++&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// b = +++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;let-match&quot;&gt;Let Match&lt;/h2&gt;
&lt;p&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;match&lt;/code&gt; statement can be used to match against an &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; pattern, which allows for more complex handling of each variant.&lt;/p&gt;

&lt;p&gt;This example accomplishes the same thing as the one above - as such it’s not that useful, but is presented as a comparison:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c&quot;&gt;// Match is an expression as well as a statement. This example shows how&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// a variable is set based on an Option enum.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// ------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+++MELON MELON MELON+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// Some variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                        &lt;span class=&quot;c&quot;&gt;// None variant&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// m is the unwrapped data from the option&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Out of Cheese Error&quot;&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// As above, but handling the None variant&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_option_empty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;// In this case we won't enter this branch&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Out of Cheese Error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// msg_2 set to this value&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg_2 = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg_2&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;c&quot;&gt;// Output:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg = +++MELON MELON MELON+++&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// msg_2 = Out of Cheese Error&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The following example shows how we might handle &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; return from a function.&lt;/p&gt;

&lt;p&gt;In this case, if the function returns the &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; variant, we print a message and end the programme early:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;//let input: Option&amp;lt;u8&amp;gt; = Some(i);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// If the Option returned by square() has Some() value, set s to this value.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// Otherwise, return early.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&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;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ans&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ans&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;square() did not return a value.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&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;c&quot;&gt;// We didn't return early, so s has a value. There is no need to unwrap.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{operand} * {operand} = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;c&quot;&gt;/// Check if arg has a value. If it does, set val to the value.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;/// Otherwise, return None. Once we have a val, return the square.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&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;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;the-if-let-idiom&quot;&gt;The if let Idiom&lt;/h2&gt;
&lt;p&gt;In the &lt;code class=&quot;highlighter-rouge&quot;&gt;square()&lt;/code&gt; function in the example above, you could write the guard clause as:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&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;c&quot;&gt;// If arg Option destructures, set val to it's value. Otherwise, enter the else block.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This has the effect of setting &lt;code class=&quot;highlighter-rouge&quot;&gt;val&lt;/code&gt; to the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;arg&lt;/code&gt; if it is the &lt;code class=&quot;highlighter-rouge&quot;&gt;Some()&lt;/code&gt; variant. If &lt;code class=&quot;highlighter-rouge&quot;&gt;arg&lt;/code&gt; is the &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; variant, the function returns early with the returned &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; being the &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; variant.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;if let&lt;/code&gt; idiom combines a pattern &lt;code class=&quot;highlighter-rouge&quot;&gt;match&lt;/code&gt; and an &lt;code class=&quot;highlighter-rouge&quot;&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;If you just want to operate on the value held by the &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; when it is of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Some()&lt;/code&gt; variant:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// The Option&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// If you just want to operate on the value held by the `Option`.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// If the option is the `None` variant, do nothing.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// &quot;If n is the `Some()` variant, bind it's value to r and use this in the&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// following block.&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// We only enter this block if n is the Some() variant &lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&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;c&quot;&gt;// This has the same result as the above if let block:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;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;p&quot;&gt;}&lt;/span&gt;

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

&lt;h3 id=&quot;failure-casefallback-required&quot;&gt;Failure Case/Fallback Required&lt;/h3&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;//Some(42);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fallback&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// If a failure case is required.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// &quot;If n is the `Some()` variant, bind it's destructured value to r and pass this&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// to the following block. Otherwise, enter the else block.&quot; &lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fallback&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;c&quot;&gt;// This has the same result as the above:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fallback&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;p&quot;&gt;}&lt;/span&gt; 

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

&lt;h3 id=&quot;save-destructured-value-into-a-variable-with-a-default&quot;&gt;Save Destructured Value into a Variable with a Default&lt;/h3&gt;
&lt;p&gt;The following example shows how to save the destructured value into a variable (in the event of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; being the &lt;code class=&quot;highlighter-rouge&quot;&gt;Some()&lt;/code&gt; variant) with a default value as a fallback:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;//Some(42);&lt;/span&gt;
   
    &lt;span class=&quot;c&quot;&gt;// Save the destructured value into a variable.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// If the Option variant is Some(), destructure it's value and save it into&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// the variable `result`. In the case of the `None` variant, set result to&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// the default value of 13.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;// Equivalent to the above:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result _2 = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/std/option.html?highlight=Option#option&quot;&gt;Rust by Example: Option&lt;/a&gt; - has a good practical example that handles divide by zero&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/std/result.html&quot;&gt;Rust by Example: Result&lt;/a&gt; - follows on from the above, with better handling of divide by zero.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://riptutorial.com/rust/example/4447/if-let---while-let&quot;&gt;Concise, clear description of if let&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 07 May 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/05/Set-Default-Values-in-Rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/05/Set-Default-Values-in-Rust/</guid>
      </item>
      
    
      
      <item>
        <title>Contrasting C and JavaScript - Make an Array of Words From a String</title>
        <description>&lt;p&gt;This article contrasts how you would make an array of strings representing the “words” in an original sentence - in other words, build an array of substrings derived from an original string, delimited by space characters or the string end.&lt;/p&gt;

&lt;p&gt;The objective is to write a function that mutates a passed-in array.&lt;/p&gt;

&lt;h2 id=&quot;c-code&quot;&gt;C Code&lt;/h2&gt;
&lt;p&gt;In C, function parameters are passed by value. The value of the parameter is copied into the function’s stack frame - any changes to the function parameter are only relevant within the scope of the function.&lt;/p&gt;

&lt;p&gt;For a function to modify data and for such changes to persist in the outside scope, the parameter must be passed as a pointer. In this way, the memory address of the “outside” variable is copied into the stack frame of the function, where it can be de-referenced to access (and change) the actual data.&lt;/p&gt;

&lt;p&gt;In the case of an array of strings, the variable to be changed in the function is already a pointer to a pointer. The base data type is a &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;, with a &lt;code class=&quot;highlighter-rouge&quot;&gt;char*&lt;/code&gt; being a pointer to a char, which can be used to represent an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt; - or when null-terminated, a string. An array of strings therefore can be represented by a pointer to a &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; - in other words, &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt; is our array of strings, to modify this in a function we need to pass in a pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;char ***&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside the function, dereferencing &lt;code class=&quot;highlighter-rouge&quot;&gt;char ***words&lt;/code&gt; once - &lt;code class=&quot;highlighter-rouge&quot;&gt;*words&lt;/code&gt; provides the pointer to a pointer that is the array of strings we’re working on.&lt;/p&gt;

&lt;p&gt;We need to make sure that the array has enough space to hold pointers to the required number of words. For this example, the required memory is allocated dynamically. This means that memory must be carefully tracked by the programmer and freed later. The code therefore includes a function to free the array, by firstly iterating over and freeing individual strings.&lt;/p&gt;

&lt;p&gt;Because memory allocation (and reallocation) is relatively expensive, the function initially allocates space for up to 10 words. Whenever a new word is detected, we check to see if this memory allocation needs to be increased. If this is the case, a &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; is performed, adding space for an extra 10 “word pointers”. We add an extra 10 rather than just a single extra pointer to avoid re-allocating memory too frequently.&lt;/p&gt;

&lt;p&gt;When saving individual words as strings in the array, we know the exact number of characters in the string. We allocate memory for these using &lt;code class=&quot;highlighter-rouge&quot;&gt;calloc()&lt;/code&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;char *tmp = calloc(wordSize + 1, sizeof(*tmp));&lt;/code&gt;. This function initialises all memory to zero, so if we initialise with one more member than we need for the word characters, the final character will be &lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt; - which serves as a null terminator and saves us the bother of null-terminating the string later.&lt;/p&gt;

&lt;p&gt;Note that all memory allocations are checked for success - if &lt;code class=&quot;highlighter-rouge&quot;&gt;calloc()&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; return &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt; we trigger a graceful exit of the programme.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Out of cheese error +++ redo from start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allocFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freeArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;***&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nAllocatedWords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nAllocatedWords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&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;n&quot;&gt;allocFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;calloc() failed.&quot;&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wordCount&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// count until next space.
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;			
		&lt;span class=&quot;c1&quot;&gt;// i is the index of the first letter of word
&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// j - 1 is the index of the last.
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&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;n&quot;&gt;wordCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wordCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nAllocatedWords&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;n&quot;&gt;nAllocatedWords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;realloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nAllocatedWords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&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;n&quot;&gt;allocFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;realloc failed.&quot;&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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wordSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wordSize&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&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;n&quot;&gt;allocFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;calloc failed.&quot;&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wordCount&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;strncpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wordCount&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;freeArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;allocFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&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;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;freeArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;javascript-code&quot;&gt;JavaScript Code&lt;/h2&gt;
&lt;p&gt;This is considerably shorter:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#!/usr/bin/env node
&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Out of cheese error +++ redo from start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; &quot;&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;nx&quot;&gt;setArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;setArray()&lt;/code&gt; function, we use the &lt;code class=&quot;highlighter-rouge&quot;&gt;split()&lt;/code&gt; method to split the string into an array of strings, delimited by a space character.&lt;/p&gt;

&lt;p&gt;This is then unpacked to individual elements by the spread syntax operator &lt;code class=&quot;highlighter-rouge&quot;&gt;...&lt;/code&gt;. These values are pushed into our array. It is possible to mutate an array within a function like this in JavaScript.&lt;/p&gt;

</description>
        <pubDate>Tue, 28 Apr 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/04/Contrasting-C-and-JavaScript-Make-an-Array-of-Words-From-a-String/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/04/Contrasting-C-and-JavaScript-Make-an-Array-of-Words-From-a-String/</guid>
      </item>
      
    
      
      <item>
        <title>Debugging C and C++ with GDB</title>
        <description>&lt;p&gt;Using a debugger allows you to investigate the state of your programme. If you’re working in C or C++, familiarity with a debugger like GDB is more or less essential.&lt;/p&gt;

&lt;p&gt;GDB is the GNU debugger - it is a tool that allows you to see what is going on “inside” your target programme while it is executing - or what a programme was doing at the moment it crashed.&lt;/p&gt;

&lt;h2 id=&quot;compiling&quot;&gt;Compiling&lt;/h2&gt;
&lt;p&gt;To use GDB, compile with &lt;em&gt;debugging symbols&lt;/em&gt;: these are extra pieces of data that help the tool determine the layout of code and data in memory.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;-g&lt;/code&gt; option instructs &lt;code class=&quot;highlighter-rouge&quot;&gt;gcc&lt;/code&gt; to compile with debugging symbols. Use &lt;code class=&quot;highlighter-rouge&quot;&gt;-ggdb3&lt;/code&gt; for the maximum amount of debugging information. If compiling in multiple steps, include &lt;code class=&quot;highlighter-rouge&quot;&gt;-ggdb3&lt;/code&gt; at each step.&lt;/p&gt;

&lt;h2 id=&quot;run-gdb&quot;&gt;Run GDB&lt;/h2&gt;
&lt;p&gt;Once the programme has been compiled with debugging symbols, run &lt;code class=&quot;highlighter-rouge&quot;&gt;gdb&lt;/code&gt; from the command line, providing the name of your executable as the sole argument: &lt;code class=&quot;highlighter-rouge&quot;&gt;gdb ./my-prog&lt;/code&gt;. If your programme requires arguments, you don’t enter them at this stage.&lt;/p&gt;

&lt;h2 id=&quot;commands-moving-through-the-programme&quot;&gt;Commands: Moving Through the Programme&lt;/h2&gt;
&lt;h3 id=&quot;run&quot;&gt;Run&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;run&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;r&lt;/code&gt;: Run the programme, or possibly restart it. The programme will run until it encounters a condition that causes it to stop - a crash, breakpoint etc.&lt;/p&gt;

&lt;h3 id=&quot;start&quot;&gt;Start&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt;: Begin (or restart) the programme. Similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;run&lt;/code&gt;, but &lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt; is the equivalent of setting a temporary breakpoint at the beginning of the main procedure. The &lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt; command stops the programme (e.g. to accept more commands) as soon as execution enters the main function - &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; in C and C++.&lt;/p&gt;

&lt;h3 id=&quot;step&quot;&gt;Step&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;step&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt;: Advance the programme one step - &lt;code class=&quot;highlighter-rouge&quot;&gt;step&lt;/code&gt; will go into called functions.&lt;/p&gt;

&lt;h3 id=&quot;next&quot;&gt;Next&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt;: Advance the program one line. Unlike step, if the current line of code is a function call, GDB will execute the entire called function without jumping into the function.&lt;/p&gt;

&lt;h3 id=&quot;repeat-commands&quot;&gt;Repeat Commands&lt;/h3&gt;
&lt;p&gt;Hit enter without entering a command to repeat the last command.&lt;/p&gt;

&lt;h3 id=&quot;command-line-arguments&quot;&gt;Command Line Arguments&lt;/h3&gt;
&lt;p&gt;To pass command line arguments, you can either add them after the &lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;run&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;r&lt;/code&gt;) command (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;r someArg anotherArg&lt;/code&gt;), or you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;set args&lt;/code&gt; to set command line arguments.&lt;/p&gt;

&lt;h2 id=&quot;examine-variables&quot;&gt;Examine Variables&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;print&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;display&lt;/code&gt; commands allow you to see what value an expression evaluates to.&lt;/p&gt;

&lt;h3 id=&quot;print&quot;&gt;Print&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;print&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt;: Evaluates an expression and prints the result. Print a variable x: &lt;code class=&quot;highlighter-rouge&quot;&gt;p x&lt;/code&gt; to show the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; at the current position in the programme.&lt;/p&gt;

&lt;p&gt;If the expression has side-effects they will affect the state of the program - if you do &lt;code class=&quot;highlighter-rouge&quot;&gt;p x = 3&lt;/code&gt;, x is set to 3 and printed.&lt;/p&gt;

&lt;p&gt;Format print:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/x&lt;/code&gt;: Integer in hexadecimal format&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/d&lt;/code&gt;: Integer in signed decimal&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/u&lt;/code&gt;: Integer in unsigned decimal&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/o&lt;/code&gt;: Integer in octal&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/t&lt;/code&gt;: Integer in binary (“t” == “two”)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/a&lt;/code&gt;: Print as an address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E.g. print variable &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; in hex format: &lt;code class=&quot;highlighter-rouge&quot;&gt;p/x i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://sourceware.org/gdb/onlinedocs/gdb/Output-Formats.html&quot;&gt;See here&lt;/a&gt; for more options.&lt;/p&gt;

&lt;p&gt;When you print the value of an expression, GDB remembers the value in internal variables which are named &lt;code class=&quot;highlighter-rouge&quot;&gt;$1&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;$2&lt;/code&gt; etc. Gdb shows the internal variable when it prints the value e.g., &lt;code class=&quot;highlighter-rouge&quot;&gt;$1 = 42&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;$&lt;/code&gt; variables can be used in subsequent expressions.&lt;/p&gt;

&lt;h3 id=&quot;print-from-array&quot;&gt;Print from Array&lt;/h3&gt;
&lt;p&gt;You can print multiple elements from an array - put &lt;code class=&quot;highlighter-rouge&quot;&gt;@number&lt;/code&gt; after an lvalue name and GDB prints &lt;code class=&quot;highlighter-rouge&quot;&gt;number&lt;/code&gt; values starting at that index.&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt; is an array, &lt;code class=&quot;highlighter-rouge&quot;&gt;p A[0]@5&lt;/code&gt; will print the first 5 elements.&lt;/p&gt;

&lt;p&gt;Print all elements in array &lt;code class=&quot;highlighter-rouge&quot;&gt;A&lt;/code&gt; of length &lt;code class=&quot;highlighter-rouge&quot;&gt;len&lt;/code&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;p *A@len&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;display&quot;&gt;Display&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;display&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;disp&lt;/code&gt;: Automatically display certain expressions each time GDB stops at a breakpoint or after a step. To display the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; at each breakpoint: &lt;code class=&quot;highlighter-rouge&quot;&gt;display i&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;investigating-the-state-of-your-program&quot;&gt;Investigating the State of Your Program&lt;/h2&gt;

&lt;h3 id=&quot;inspect-stack-frames&quot;&gt;Inspect Stack Frames&lt;/h3&gt;
&lt;p&gt;GDB allows you to inspect the current set of stack frames and move up and down within them. The &lt;code class=&quot;highlighter-rouge&quot;&gt;backtrace&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;bt&lt;/code&gt;) command lists all of the stack frames with the current one on top, and main on the bottom - showing the function calls that lead up to the current position. The &lt;code class=&quot;highlighter-rouge&quot;&gt;backtrace&lt;/code&gt; also shows the line where each call was made.&lt;/p&gt;

&lt;p&gt;Gdb uses the variables in the current scope when executing the &lt;code class=&quot;highlighter-rouge&quot;&gt;print&lt;/code&gt; command. To inspect variables in other frames further up the stack, select different frames with the &lt;code class=&quot;highlighter-rouge&quot;&gt;up&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;down&lt;/code&gt; command, which move scope up and down the stack.&lt;/p&gt;

&lt;p&gt;If the programme stops in a failed assert GDB will stop deep inside the C library - in the code that handles assert. The code under examination is likely to be a number of stack frames up. Use the &lt;code class=&quot;highlighter-rouge&quot;&gt;up&lt;/code&gt; command a few times until GDB enters the appropriate frame.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;info&lt;/code&gt; command provides information about various aspects of the programme. This command has various subcommands:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;info frame&lt;/code&gt; describes the memory layout of the current frame&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;info types&lt;/code&gt; describes the types that are in the current program&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;info b&lt;/code&gt; information about breakpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There more &lt;code class=&quot;highlighter-rouge&quot;&gt;info&lt;/code&gt; options - use &lt;code class=&quot;highlighter-rouge&quot;&gt;help info&lt;/code&gt; for more information.&lt;/p&gt;

&lt;h2 id=&quot;controlling-execution&quot;&gt;Controlling Execution&lt;/h2&gt;
&lt;h3 id=&quot;kill-gdb&quot;&gt;Kill GDB&lt;/h3&gt;
&lt;p&gt;To kill GDB and restart a fresh debugging session without restarting GDB: &lt;code class=&quot;highlighter-rouge&quot;&gt;ki&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;kill&lt;/code&gt;) and enter ‘y’.&lt;/p&gt;

&lt;h3 id=&quot;next-and-step&quot;&gt;Next and Step&lt;/h3&gt;
&lt;p&gt;Start the programme with &lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt;, then step through execution line by line.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt;) and &lt;code class=&quot;highlighter-rouge&quot;&gt;step&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt;) commands advance the state of the program line-by-line.&lt;/p&gt;

&lt;h3 id=&quot;breakpoints&quot;&gt;Breakpoints&lt;/h3&gt;
&lt;p&gt;A breakpoint instructs GDB to stop execution whenever the program reaches a particular line.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;# Breakpoint inside function main() - break inserted just after opening curly brace:
b main
Breakpoint 1 at 0x4007de: file main.c, line 6.

# Breakpoint in file main.c on line 42:

b main.c:42
Breakpoint 2 at 0x4009b5: file main.c, line 43.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Breakpoints are set with the &lt;code class=&quot;highlighter-rouge&quot;&gt;break&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;) command, followed by either a line number or a function name (meaning to set the breakpoint at the start of that function).&lt;/p&gt;

&lt;p&gt;When you set a breakpoint, GDB assigns it an ID number.&lt;/p&gt;

&lt;p&gt;The programme runs (or continues if already started) until the breakpoint. When the breakpoint is encountered, GDB pauses execution and allows you to inspect the state of the programme at this point.&lt;/p&gt;

&lt;p&gt;You can enter &lt;code class=&quot;highlighter-rouge&quot;&gt;c&lt;/code&gt; to continue from the breakpoint, which jumps to the next breakpoint. You can also use &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt; to step through the programme from this point.&lt;/p&gt;

&lt;p&gt;By default, breakpoints are unconditional. GDB will stop the program and give you control anytime it reaches the appropriate line.&lt;/p&gt;

&lt;h3 id=&quot;conditional-breakpoint&quot;&gt;Conditional Breakpoint&lt;/h3&gt;
&lt;p&gt;Conditional breakpoints are very useful for looking inside loops and recursive reoutines.&lt;/p&gt;

&lt;p&gt;Break on line 7 if &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; is as specified:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(gdb) break 7 if i==2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id=&quot;breakpoint-info&quot;&gt;Breakpoint Info&lt;/h3&gt;

&lt;p&gt;Show info on currently set breakpoints:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004007de in main at main.c:6
2       breakpoint     keep y   0x00000000004009b5 in main at main.c:43
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;delete-all-breakpoints&quot;&gt;Delete all Breakpoints&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;delete&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;del&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;d&lt;/code&gt; and enter ‘y’ to confirm.&lt;/p&gt;

&lt;h3 id=&quot;delete-specific-breakpoint&quot;&gt;Delete Specific Breakpoint&lt;/h3&gt;
&lt;p&gt;Get the ID using &lt;code class=&quot;highlighter-rouge&quot;&gt;info b&lt;/code&gt; then &lt;code class=&quot;highlighter-rouge&quot;&gt;d x&lt;/code&gt; to delete breakpoint with id x.&lt;/p&gt;

&lt;h3 id=&quot;disable-all-breakpoints&quot;&gt;Disable all Breakpoints&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;disable&lt;/code&gt; with no arguments to disable all breakpoints. To enable, enter &lt;code class=&quot;highlighter-rouge&quot;&gt;enable x&lt;/code&gt; where &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; is the ID of the breakpoint in question.&lt;/p&gt;

&lt;h3 id=&quot;disable-specific-breakpoints&quot;&gt;Disable Specific Breakpoints&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;disable x

# disable multiple, space separated:
disable x y
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;save-and-reload-breakpoints&quot;&gt;Save and Reload Breakpoints&lt;/h3&gt;
&lt;p&gt;Save current breakpoints into a file &lt;code class=&quot;highlighter-rouge&quot;&gt;bp-store.txt&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;save breakpoints bp-store.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To reload:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;source bp-store.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;backtrace&quot;&gt;Backtrace&lt;/h2&gt;
&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;bt&lt;/code&gt; after programme interruption to see a backtrace - a list of function calls, representing the call stack. The top line is the frame that was current when the programme was interrupted.&lt;/p&gt;

&lt;p&gt;Use the &lt;code class=&quot;highlighter-rouge&quot;&gt;frame&lt;/code&gt; command to inspect a specified frame.&lt;/p&gt;

&lt;h2 id=&quot;watchpoints&quot;&gt;Watchpoints&lt;/h2&gt;
&lt;p&gt;A watchpoint stops execution when the value of an expression changes. The simplest use is to watch the value of a single variable - the command &lt;code class=&quot;highlighter-rouge&quot;&gt;watch i&lt;/code&gt; causes a break whenever the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; changes, printing the old &amp;amp; new values.&lt;/p&gt;

&lt;p&gt;Watchpoints can be useful when debugging pointer-related issues.&lt;/p&gt;

&lt;p&gt;If the alias (variable) associated with the watchpoint goes out of scope before changing, you can find the relevant GDB variable (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;$1&lt;/code&gt;) by using &lt;code class=&quot;highlighter-rouge&quot;&gt;print&lt;/code&gt; and this (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;watch $1&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html&quot;&gt;More info on watchpoints&lt;/a&gt;, or enter &lt;code class=&quot;highlighter-rouge&quot;&gt;info gdb&lt;/code&gt; and search for &lt;code class=&quot;highlighter-rouge&quot;&gt;watchpoint&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;signals&quot;&gt;Signals&lt;/h2&gt;
&lt;p&gt;When a programme receives a signal, GDB will stop the programme and give you control.&lt;/p&gt;

&lt;h3 id=&quot;sigsegv&quot;&gt;SIGSEGV&lt;/h3&gt;
&lt;p&gt;Indicates a segmentation fault. The programme has attempted to access a restricted area of memory.&lt;/p&gt;

&lt;p&gt;Execution stops the programme on the line where the segfault happened. You can inspect the state of the program (printing out variables) to see what went wrong.&lt;/p&gt;

&lt;h3 id=&quot;sigabrt&quot;&gt;SIGABRT&lt;/h3&gt;
&lt;p&gt;Programme calls &lt;code class=&quot;highlighter-rouge&quot;&gt;abort()&lt;/code&gt; or fails an assert. GDB leaves you in control of the programme at the point where assert caused the abort. You may need to move through frames to get back into your own code to debug the fault.&lt;/p&gt;

&lt;h3 id=&quot;sigint&quot;&gt;SIGINT&lt;/h3&gt;
&lt;p&gt;Programme is interrupted - e.g. by the user pressing Control-c. If the programme is getting stuck in an infinite loop, run it in GDB and press Control-c. Once execution has halted use &lt;code class=&quot;highlighter-rouge&quot;&gt;bt&lt;/code&gt; to view a backtrace. To examine a particular frame, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;frame&lt;/code&gt; command, e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;(gdb) f 4&lt;/code&gt; to inspect frame 4.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/onlinedocs/gdb/&quot;&gt;Debugging with GDB&lt;/a&gt; - online book&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.fayewilliams.com/2011/02/01/command-line-gdb-tutorial-and-walkthrough-part-1/&quot;&gt;GDB Tutorial&lt;/a&gt; by Faye Williams - loads of useful GDB stuff on the same site&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html&quot;&gt;Watchpoints&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 16 Apr 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/04/Debugging-C-and-C++-with-GDB/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/04/Debugging-C-and-C++-with-GDB/</guid>
      </item>
      
    
      
      <item>
        <title>Pointer Arithmetic &amp; Multiple Dereferencing in C</title>
        <description>&lt;p&gt;It’s useful to really understand pointer arithmetic in C - though in most situations you’d probably be better off using the array subscript operator (&lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; dereferencing operator has precedence over the addition &lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;For the following examples, we’ll use multiple indirection to create an abstract data structure &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; to represent this string:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello world. abc def.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;xyz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;…as a multidimensional array. The string could be represented as a document &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; whereby:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt;: contains multiple &lt;code class=&quot;highlighter-rouge&quot;&gt;paragraphs&lt;/code&gt; - sequences of characters delimited by newline (‘\n’) characters&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;paragraph&lt;/code&gt;: contains multiple sentences - sequences of characters delimited by fullstop (‘.’) characters&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sentence&lt;/code&gt;: contains multple words -sequences of characters delimited by space (‘ ‘) characters&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;word&lt;/code&gt;: contains multiple characters, with no spaces and terminated by a &lt;code class=&quot;highlighter-rouge&quot;&gt;NUL&lt;/code&gt; character&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The underlying data type in this example is a &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;. This means:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Words are pointers to &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;s (an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;s): &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Sentences are pointers to words (an array of arrays): &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Paragraphs are pointers to sentences (an array of arrays of arrays): &lt;code class=&quot;highlighter-rouge&quot;&gt;char ***&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The Document is a pointer to paragraph(s) - an array of arrays of arrays of arrays: &lt;code class=&quot;highlighter-rouge&quot;&gt;char****&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re trying to wrap your head around multiple indirection, I strongly recommend:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creating a simple programme with a data structure like the one shown below.&lt;/li&gt;
  &lt;li&gt;Run the programme with GDB, and attempt to dereference the various elements, as shown at the end of this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;data-structure&quot;&gt;Data Structure&lt;/h2&gt;
&lt;p&gt;If you’re more used to using the array index operator &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;, you can think of the data structure like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;char *doc[2][5][10]

// alternatively, allocate space dynamically:
// char ****doc = NULL;

// Assume space has been allocated:
doc[0][0][0] = &quot;hello&quot;;
doc[0][0][1] = &quot;world&quot;;
doc[0][1][0] = &quot;abc&quot;;
doc[0][1][1] = &quot;def&quot;;
doc[1][0][0] = &quot;xyz&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Resulting Data structure:&lt;/p&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Document
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Paragraph 0
&lt;/span&gt;	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Sentence 0
&lt;/span&gt;		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;world&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Sentence 1
&lt;/span&gt;		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;def&quot;&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;c1&quot;&gt;// Paragraph 1
&lt;/span&gt;	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Sentence 0
&lt;/span&gt;		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;xyz&quot;&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;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;dereferencing&quot;&gt;Dereferencing&lt;/h2&gt;

&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt;: This variable holds the address of the first highest level array - a pointer to first (zero index) paragraph&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*doc&lt;/code&gt;: Dereference &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; to get a pointer to the first sentence in the first paragraph.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;**doc&lt;/code&gt;: Dereference this to get a pointer to the first word in the first sentence of the first paragraph. &lt;strong&gt;This happens next&lt;/strong&gt; because &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; has precedence over &lt;code class=&quot;highlighter-rouge&quot;&gt;+&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;**doc + 1&lt;/code&gt;: Add 1 to this to move the pointer to the second word of the sentence.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(**doc + 1)&lt;/code&gt;: Dereference this to get a printable string - a pointer to a null terminated array of chars.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Output: &quot;world&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;example-1&quot;&gt;Example&lt;/h3&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&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;o&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*doc + 1&lt;/code&gt;: Dereference &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; to get a pointer to first sentence in paragraph 0, then add 1 to get a pointer to sentence 2.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(*doc + 1) + 1&lt;/code&gt;: Dereference the pointer to sentence to get a pointer to first word, add 1 to get a pointer to second word.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(*(*doc + 1) + 1)&lt;/code&gt;: Dereference this to print the string.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&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;o&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;c1&quot;&gt;// Output: &quot;def&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;general-dereferencing-heuristic&quot;&gt;General Dereferencing Heuristic&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//                          para index 0
//                          |
//                          |    sentence index 1
//                          |    |
//                          |    |    word index 0
//                          |    |    |
//                          |    |    |    character index 1
//                          ↓    ↓    ↓    ↓ 
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;letter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&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;o&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;o&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;o&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;c1&quot;&gt;// equivalent:
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;letter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&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;mi&quot;&gt;1&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;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;more-examples&quot;&gt;More Examples&lt;/h2&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// GDB output
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;112&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'d'&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;101&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'e'&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;114&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;102&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'f'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;****&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;doc&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;mi&quot;&gt;0&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doc&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;mi&quot;&gt;0&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;world&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doc&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;mi&quot;&gt;1&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doc&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;mi&quot;&gt;1&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;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;def&quot;&lt;/span&gt;

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

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// GDB output
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x602680&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;118&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6026a0&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;world&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*doc&lt;/code&gt;: Dereference &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; once, giving a pointer to the first sentence in the first paragraph.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*doc + 1&lt;/code&gt;: Add 1 to this value - providing a pointer to the second sentence.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(*doc + 1)&lt;/code&gt;: Dereference this, giving a sentence (an array of words).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(*doc + 1) + 0&lt;/code&gt;: Add zero to pointer - which still points to the first array of words (sentence).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*(*(*doc + 1) + 0)&lt;/code&gt;: Dereference this to print, generating tdoche first word in the second sentence of the first paragraph&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// GDB output
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;119&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6026c0&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;abc&quot;&lt;/span&gt;


&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;o&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;o&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;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6026e0&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;def&quot;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 09 Apr 2020 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2020/04/Pointer-Arithmetic-&amp;-Multiple-Dereferencing-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/04/Pointer-Arithmetic-&amp;-Multiple-Dereferencing-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Build Python from Source in Linux</title>
        <description>&lt;p&gt;Get the latest version of Python on Ubuntu&lt;/p&gt;

&lt;p&gt;Download the latest version of Python from here: &lt;a href=&quot;https://www.python.org/downloads/&quot;&gt;https://www.python.org/downloads/&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Download Python:&lt;/span&gt;
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz

&lt;span class=&quot;c&quot;&gt;# Download the detached signature file:&lt;/span&gt;
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz.asc
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;verify-download&quot;&gt;Verify Download&lt;/h2&gt;
&lt;p&gt;Checksums (MD5) are presented on the &lt;code class=&quot;highlighter-rouge&quot;&gt;dowloads/releases/python-xxx/&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;Check the &lt;code class=&quot;highlighter-rouge&quot;&gt;md5sum&lt;/code&gt; manually by running:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;md5sum Python-3.8.2.tgz
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can also automate the check by building a suitable manifest file and checking this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Get md5 checksum from website, filename corresponds to the download&lt;/span&gt;
cat &amp;gt; manifest
f9f3768f757e34b342dbc06b41cbc844  Python-3.8.2.tgz

&lt;span class=&quot;c&quot;&gt;# Ctrl-d to exit cat&lt;/span&gt;
md5sum -c checksum 2&amp;gt;&amp;amp;1 | grep OK 
&lt;span class=&quot;c&quot;&gt;# Output if correct:&lt;/span&gt;
Python-3.8.2.tgz: OK
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The website also posts the filesize, so you should also check this.&lt;/p&gt;

&lt;h3 id=&quot;import-relevant-gpg-key-from-trusted-server&quot;&gt;Import Relevant GPG Key From Trusted Server&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Imports key sourced here: https://www.python.org/downloads/&lt;/span&gt;
gpg --keyserver keyserver.ubuntu.com --recv-keys B26995E310250568
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Check that the downloaded file has been signed by this key:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Reference the signature file&lt;/span&gt;
gpg --verify Python-3.8.2.tgz.asc
&lt;span class=&quot;c&quot;&gt;# Correct output:&lt;/span&gt;
gpg: assuming signed data &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;Python-3.8.2.tgz&lt;span class=&quot;s1&quot;&gt;'
gpg: Signature made Tue 25 Feb 2020 10:41:46 GMT using RSA key ID 10250568
gpg: Good signature from &quot;Łukasz Langa (GPG langa.pl) &amp;lt;lukasz@langa.pl&amp;gt;&quot;
gpg:                 aka &quot;Łukasz Langa &amp;lt;lukasz@python.org&amp;gt;&quot;
gpg:                 aka &quot;Łukasz Langa (Work e-mail account) &amp;lt;ambv@fb.com&amp;gt;&quot;
gpg:                 aka &quot;[jpeg image of size 24479]&quot;
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: E3FF 2839 C048 B25C 084D  EBE9 B269 95E3 1025 0568
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;extract&quot;&gt;Extract&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tar -xvf Python-3.8.2.tgz
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This unpacks files into a directory (in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;Python-3.8.2&lt;/code&gt;) which you should move into:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;Python-3.8.2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Check out the &lt;code class=&quot;highlighter-rouge&quot;&gt;README.rst&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;build&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./configure --enable-optimizations
make
make &lt;span class=&quot;nb&quot;&gt;test
&lt;/span&gt;sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will install Python as &lt;code class=&quot;highlighter-rouge&quot;&gt;python3&lt;/code&gt;.&lt;/p&gt;

</description>
        <pubDate>Tue, 24 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Build-Python-from-Source-in-Linux/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Build-Python-from-Source-in-Linux/</guid>
      </item>
      
    
      
      <item>
        <title>Memoization when Computing Fibonacci Sequence in C</title>
        <description>&lt;p&gt;The objective of this exercise is to compute a Fibonacci sequence up to a target number of elements, saving the sequence as an array.&lt;/p&gt;

&lt;p&gt;The Fibonacci sequence is the sequence of numbers such that each number is the sum of the two preceding numbers, starting from 0 and 1. For example, the first 6 Fibonacci numbers are:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0, 1, 1, 2, 3, 5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The exercise contrasts two methods:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Iterative, using a for loop and computing values in order&lt;/li&gt;
  &lt;li&gt;Recursive, using dynamic programming technique (memoization) to improve efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;iterative&quot;&gt;Iterative&lt;/h2&gt;
&lt;p&gt;The iterative method is straightforward - loop from zero up to the target, setting the current element to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;0 if the current element is at index 0.&lt;/li&gt;
  &lt;li&gt;1 if the current element is at index 1.&lt;/li&gt;
  &lt;li&gt;The sum of the elements at the previous two adjacent indices otherwise.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iterativeFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;recursive-with-dynamic-programming-caching&quot;&gt;Recursive, with Dynamic Programming Caching&lt;/h2&gt;
&lt;p&gt;Simple recursive calls (in a tree structure) would involve multiple repeat calls performing the same calculation.&lt;/p&gt;

&lt;p&gt;Computing the 4th number in the Fibonacci sequence would involve calling:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fib(4)&lt;/code&gt; once&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fib(3)&lt;/code&gt; once&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fib(2)&lt;/code&gt; twice&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fib(1)&lt;/code&gt; three times&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fib(0)&lt;/code&gt; twice&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fib(4)
|     \
|      \
|       \
|        \
fib(3)	  fib(2)--
|    \     \      \
|     \	    \      \
|      \     \      \	
fib(2) fib(1) fib(1) fib(0)
|    \
|     \
|      \
fib(1)	fib(0)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For example, a naive recursive implementation in C looks like this:&lt;/p&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The number of function calls grows out of proportion as you calculate higher numbers in the sequence: computing the 10th number in the Fibonacci sequence calls &lt;code class=&quot;highlighter-rouge&quot;&gt;fib()&lt;/code&gt; 177 times - computing the 20th number calls &lt;code class=&quot;highlighter-rouge&quot;&gt;fib()&lt;/code&gt; 21891 times. Each call to the function requires a stack frame, so this approach is quite inefficient both in terms of time and space complexity.&lt;/p&gt;

&lt;p&gt;We can do better by storing results as we go - a dynamic programming technique called &lt;em&gt;memoization&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;memoization&quot;&gt;Memoization&lt;/h3&gt;
&lt;p&gt;This can be implemented by using an array to hold successive numbers in the sequence. For each recursive call, we check to see if the value has already been computed by looking in the cache. If has been previously computed, we return this value. Otherwise, we perform the computation and add this to the cache.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define N 10
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iterativeFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
* Build a cache representing the Fibonacci sequence.
* Note that the second parameter is an array index which allows the cache to
* be checked for the required element. 
*/&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;recursiveFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// For analysis only
&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// If the cache holds -1 at the required index, it has not yet been computed.
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recursiveFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recursiveFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[ %d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, %d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; ]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;iterativeFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	
	&lt;span class=&quot;c1&quot;&gt;// Initialise an array of N elements, each element set to -1
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// Note that this is a GNU extension to the GCC compiler
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&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;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;o&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Set the first two elements in the sequence, which are known
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;cache&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;o&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;n&quot;&gt;cache&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;o&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;c1&quot;&gt;// The function receives a pointer to the cache array and the index of the last element.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;recursiveFibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;recursiveFibonacci() called %lu times.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Using this method, computing the 20th number in the Fibonacci sequence requires 37 calls to &lt;code class=&quot;highlighter-rouge&quot;&gt;recursiveFibonacci()&lt;/code&gt;, compared with the 21891 calls that are required if caching is not used. We also have the additional benefit of having the entire sequence up to and including our target in our cache array, for very little extra cost.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://cs.stackexchange.com/a/99517/104932&quot;&gt;SO answer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.topcoder.com/community/competitive-programming/tutorials/dynamic-programming-from-novice-to-advanced/&quot;&gt;Dynamic Programming from Novice to Advanced&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 23 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Memoization-when-Computing-Fibonacci-Sequence-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Memoization-when-Computing-Fibonacci-Sequence-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Binary Search in Rust</title>
        <description>&lt;p&gt;Binary search is an algorithmically efficient way of searching an ordered array. It works by comparing the target value with the middle element of the array. If the two are not equal, the array is partitioned and re-searched, this time excluding the elements that are either too high or too low.&lt;/p&gt;

&lt;p&gt;For example, if the target value is 42, and the middle element of an ordered array is 100, the target cannot lie in the elements from the mid point to the end of the array. This allows us to reset the search bounds, eliminating half of the previous array at each step.&lt;/p&gt;

&lt;h2 id=&quot;binary-search-in-rust-iiterative&quot;&gt;Binary search in Rust: Iiterative&lt;/h2&gt;
&lt;p&gt;Arguments: Array slice, array length, target integer to look up.&lt;/p&gt;

&lt;p&gt;The initial value for &lt;code class=&quot;highlighter-rouge&quot;&gt;low&lt;/code&gt; (index of the first array element) is 0.&lt;/p&gt;

&lt;p&gt;The initial value for &lt;code class=&quot;highlighter-rouge&quot;&gt;high&lt;/code&gt; (index of the last array element) is length - 1.&lt;/p&gt;

&lt;h3 id=&quot;algorithm&quot;&gt;Algorithm&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Determine the index of the middle element if length is odd or the lowest of the pair of middle elements if length is even.&lt;/li&gt;
  &lt;li&gt;The mid index is ⌊(high - low) / 2⌋ + low.&lt;/li&gt;
  &lt;li&gt;Compare the value at this index with the target.&lt;/li&gt;
  &lt;li&gt;If the values are the same, return the index.
    &lt;ul&gt;
      &lt;li&gt;4a. If the target &amp;gt; value, search elements at higher indices (because elements indexed by these have higher values). Set low to mid + 1&lt;/li&gt;
      &lt;li&gt;4b. If the target &amp;lt; value, search elements with lower indices (these have lower values). Set high to mid - 1&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Keep doing steps 1 to 5 until the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;low&lt;/code&gt; is greater than that of &lt;code class=&quot;highlighter-rouge&quot;&gt;high&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;If the function has not returned an index by this point, the returned option will be &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To fully search the array, the type of the &lt;code class=&quot;highlighter-rouge&quot;&gt;high&lt;/code&gt; variable be such that the variable can hold a negative value.&lt;/p&gt;

&lt;h2 id=&quot;rust&quot;&gt;Rust&lt;/h2&gt;
&lt;p&gt;Rust is really strict about types and casting - there is no implicit type conversion between primitives.&lt;/p&gt;

&lt;p&gt;Because of this, and the fact that &lt;code class=&quot;highlighter-rouge&quot;&gt;high&lt;/code&gt; must be able to handle negative numbers, computing &lt;code class=&quot;highlighter-rouge&quot;&gt;mid_index&lt;/code&gt; firstly involves manipulating &lt;code class=&quot;highlighter-rouge&quot;&gt;i8&lt;/code&gt; integers to perform the arithmetic, before overtly casting the result into a &lt;code class=&quot;highlighter-rouge&quot;&gt;usize&lt;/code&gt; type that can be used to index the array.&lt;/p&gt;

&lt;p&gt;Note that the &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; type is ideal for the function return value - it allows us to return (and handle)  a &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; option if the target does not exist in the array. In languages without this capability, we might return -1 to indicate non-membership of the array - but this is not as overtly descriptive as &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt;!&lt;/p&gt;

&lt;h2 id=&quot;code&quot;&gt;Code&lt;/h2&gt;
&lt;p&gt;The example below also includes a couple of tests.&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c&quot;&gt;// Binary search, iterative.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// Arguments: Array slice, array length, target integer to look up.&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iterative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i8&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;high&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i8&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mid_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mid_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mid_index&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;c&quot;&gt;// Search values that are greater than val - to right of current mid_index&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mid&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c&quot;&gt;// Search values that are less than val - to the left of current mid_index&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mid&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;#[test]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;correct_iterative&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correct_arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;107&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;133&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;155&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;162&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;188&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;199&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;222&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.correct_arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&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;nd&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iterative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correct_arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correct_arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correct_arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;#[test]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;incorrect_iterative&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searched_arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;107&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;133&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;155&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;162&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;188&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;199&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;222&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;incorrect_arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;61&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;84&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;119&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;132&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;154&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;160&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;177&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;187&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;197&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;201&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;211&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2242&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.incorrect_arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&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;nd&quot;&gt;assert_eq!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;iterative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searched_arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searched_arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;incorrect_arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Calling code:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;107&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;133&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;155&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;162&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;188&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;mi&quot;&gt;199&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;222&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rust_binary_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;iterative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{} found at index {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{} not found.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;similar-functionality-in-c&quot;&gt;Similar Functionality in C++&lt;/h2&gt;
&lt;p&gt;Note that it returns -1 if the target value is not found in the array.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Iterative algorithm: binary search
// 1. Set values for low and high indices - starting condition, low == 0, high == len -1.
// 2. Determine the mid index (or leftmost mid index if length is even)
// 3. If value at the mid index == target value, return the index.
// 4. If value at the mid index &amp;gt; target value, make a partition of elements with indices &amp;lt; mid index.
// 5. If value at the mid index &amp;lt; target value, make a partition of elements with indices &amp;gt; mid index.
// 6. Repeat until:
//	- low &amp;gt; high
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;binarySearchIterative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;targetVal&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;midIndex&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;low&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;high&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;n&quot;&gt;midIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;midIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;targetVal&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;midIndex&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;targetVal&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;n&quot;&gt;high&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;midIndex&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;continue&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;targetVal&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;n&quot;&gt;low&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;midIndex&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;continue&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;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 22 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Binary-Search-in-Rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Binary-Search-in-Rust/</guid>
      </item>
      
    
      
      <item>
        <title>Some or None - Handling Rust Options</title>
        <description>
</description>
        <pubDate>Sat, 21 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Some-None-Handling-Rust-Options/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Some-None-Handling-Rust-Options/</guid>
      </item>
      
    
      
      <item>
        <title>The Rust Ownership Model</title>
        <description>&lt;p&gt;Rust manages heap memory through a system of ownership, whereby the compiler checks a set of rules at compile time.&lt;/p&gt;

&lt;p&gt;Ownership features do not slow down the compiled code - if the code has compiled, it has satisfied all necessary ownership requirements.&lt;/p&gt;

&lt;h2 id=&quot;ownership-rules&quot;&gt;Ownership Rules&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Each value has a variable called it’s &lt;em&gt;owner&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;There can only be one owner at a time.&lt;/li&gt;
  &lt;li&gt;When the owner goes out of scope, the value is dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a value is heap allocated (i.e. it’s size is not known at compile time), copies are shallow by default and the original is invalidated. This is like a C++ move.&lt;/p&gt;

&lt;p&gt;When a variable that includes heap-allocated data goes out of scope, the value is cleaned up by &lt;code class=&quot;highlighter-rouge&quot;&gt;drop&lt;/code&gt; unless the data has been moved - i.e. another variable has taken ownership.&lt;/p&gt;

&lt;h2 id=&quot;rules-of-borrowing&quot;&gt;Rules of Borrowing&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Unlimited borrows for read-only borrows: let a = &amp;amp;x&lt;/li&gt;
  &lt;li&gt;For a read only borrow, the original data is immutable for the duration of the borrow&lt;/li&gt;
  &lt;li&gt;You can only have a single borrow at a time for mutable borrows: &lt;code class=&quot;highlighter-rouge&quot;&gt;let a = &amp;amp;mut x&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;example-borrow&quot;&gt;Example Borrow&lt;/h2&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// Line 1 output&lt;/span&gt;
    
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&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;err&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// You can't access a at this point because it has been mutably borrowed&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// from. The following line won't compile, with the error message:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// `cannot borrow `a` as immutable because it is also borrowed as mutable`:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;// println!(&quot;a: {:?}&quot;, a);&lt;/span&gt;

        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// Line 2 output&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;b: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// lIne 3 output&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// The borrow is scope-dependent - a is accessible again because the &lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// variable that borrowed it is out of scope:&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;a: {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// Line 4 output&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[1, 2, 3, 4]
b: [1, 2]
b: [42, 2]
a: [42, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;rust-references&quot;&gt;Rust References&lt;/h2&gt;
&lt;p&gt;Two kinds:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Shared reference: &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Mutable reference: &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;mut&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A reference cannot outlive it’s referent.&lt;/p&gt;

&lt;p&gt;A mutable reference cannot be aliased.&lt;/p&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;aliased&lt;/code&gt; is &lt;a href=&quot;https://doc.rust-lang.org/nomicon/references.html&quot;&gt;not yet defined&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-rules-of-referencing&quot;&gt;The Rules of Referencing&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;At any given time, you can have &lt;em&gt;either&lt;/em&gt; one mutable reference or any number of immutable references.&lt;/li&gt;
  &lt;li&gt;References must always be valid - dangling pointers won’t compile - the thing being referred to must be in scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;aliasing&quot;&gt;Aliasing&lt;/h2&gt;
&lt;p&gt;Variables and pointers &lt;code class=&quot;highlighter-rouge&quot;&gt;alias&lt;/code&gt; if they refer to overlapping regions of memory.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html&quot;&gt;Rust book on ownership&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html&quot;&gt;References &amp;amp; Borrowing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 21 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Rust-Ownership-Model/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Rust-Ownership-Model/</guid>
      </item>
      
    
      
      <item>
        <title>FizzBuzz in C - without the Modulus Operator</title>
        <description>&lt;p&gt;Code for this article can be found &lt;a href=&quot;https://github.com/csknk/fizzbuzz-no-modulus-operator&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FizzBuzz - iterate over a range of numbers and print:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Fizz” if the number is divisible by 3.&lt;/li&gt;
  &lt;li&gt;“Buzz” if the number is divisible by 5.&lt;/li&gt;
  &lt;li&gt;“FizzBuzz” if the number is divisible by both 3 and 5.&lt;/li&gt;
  &lt;li&gt;The number if it is not divisible by either 3 or 5.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the purposes of this exercise, use of the modulus operator &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; is disallowed. There’s no particular reason for this - it’s just an exercise.&lt;/p&gt;

&lt;h2 id=&quot;divisibility-by-three&quot;&gt;Divisibility by Three&lt;/h2&gt;
&lt;p&gt;This can be determined by comparing the sum of odd binary digits (mod 3) with the sum of even binary digits (mod 3). If these values are equal, then the number is divisible by 3.&lt;/p&gt;

&lt;h3 id=&quot;example-1&quot;&gt;Example 1&lt;/h3&gt;

&lt;p&gt;42&lt;/p&gt;

&lt;p&gt;Represented in binary digits, “even” bits marked:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;↓   ↓   ↓
1 0 1 0 1 0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Sum of odd bits = &lt;code class=&quot;highlighter-rouge&quot;&gt;0 + 0 + 0 ≡ 0 mod 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sum of even bits = &lt;code class=&quot;highlighter-rouge&quot;&gt;1 + 1 + 1 ≡ 0 mod 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are equal, so 42 is divisible by 3.&lt;/p&gt;

&lt;h3 id=&quot;example-2&quot;&gt;Example 2&lt;/h3&gt;

&lt;p&gt;43&lt;/p&gt;

&lt;p&gt;Represented in binary digits, “even” bits marked:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;↓   ↓   ↓
1 0 1 0 1 1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Sum of odd bits = &lt;code class=&quot;highlighter-rouge&quot;&gt;0 + 0 + 1 ≡ 1 mod 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sum of even bits = &lt;code class=&quot;highlighter-rouge&quot;&gt;1 + 1 + 1 ≡ 0 mod 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These are not equal, so 42 is divisible by 3.&lt;/p&gt;

&lt;p&gt;This algorithm still requires you to calculate the modulus of the sum of bits. Because the operand will have limited size, we can compute this by repeated subtraction. For a 32 bit integer, the maximum size of the operand will be 16 (i.e. the sum of 16 bits) which requires a maximum 5 subtractions.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &quot;integer-input.h&quot;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BITS_IN_BYTE 8
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * Determine mod 3 of input without using modulus operator.
 * Input should not be a large number - in this context it will
 * be at most 16 (assuming a 4 byte integer, this function will
 * receive at most the sum of 16 bits (i.e. 16)
 * */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mod_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&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;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&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;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&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;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&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;cm&quot;&gt;/**
 * Check that an integer x is divisible by 3 without using the modulus
 * operator.
 *
 * For a number to be divisible by 3, the sum of the odd bits mod 3 should equal
 * the sum of the even bits mod 3.
 * */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divByThree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oddSum&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evenSum&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Because the mask shifts 2 bits to the left each iteration,
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// we only need to iterate half the number of bits times.
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BITS_IN_BYTE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask_1&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;n&quot;&gt;oddSum&lt;/span&gt;&lt;span class=&quot;o&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask_2&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;n&quot;&gt;evenSum&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;mask_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;mask_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;oddSum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evenSum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;An alternative algorithm to determine divisibility by three:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sum all decimal digits in the number.&lt;/li&gt;
  &lt;li&gt;Repeat the summation of digits until a single digit remains.&lt;/li&gt;
  &lt;li&gt;If this value is divisible by 3, the original number is divisible by 3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;divisibility-by-five&quot;&gt;Divisibility by Five&lt;/h2&gt;
&lt;p&gt;A number is divisible by five if it’s least significant decimal digit is either 5 or 0:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * A number is divisible by 5 if the least significant decimal digit is either 5 or 0.
 * */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divByFive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finalDecimalDigit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finalDecimalDigit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finalDecimalDigit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;fizzbuzz&quot;&gt;FizzBuzz&lt;/h2&gt;
&lt;p&gt;Both our divisibility functions return 1 if the number is divisible and 0 if not. This makes it straightforward to perform the necessary logic to implement FizzBuzz:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputInteger&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divByFive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divByThree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d: FizzBuzz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;continue&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divByThree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d: Fizz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;continue&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divByFive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d: Buzz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;continue&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;p&quot;&gt;}&lt;/span&gt;

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

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/fizzbuzz-no-modulus-operator&quot;&gt;GitHub Repo&lt;/a&gt; for this article&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 21 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/FizzBuzz-in-C-without-the-Modulus-Operator/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/FizzBuzz-in-C-without-the-Modulus-Operator/</guid>
      </item>
      
    
      
      <item>
        <title>Declare Default Values for Mutable Types in Python</title>
        <description>&lt;p&gt;If you want to specify a default for a function argument of an immutable type in Python, you assign the default in the function declaration.&lt;/p&gt;

&lt;p&gt;You can’t assign a default value for an immutable type in this way. Instead, you can assign a default value &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; and check for this inside the function - if the passed-in argument is &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt;, then assign a default:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# If a dict is passed in, set self.children to this, otherwise&lt;/span&gt;
	&lt;span class=&quot;c&quot;&gt;# set it to an empty dict.&lt;/span&gt;
	&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_end&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_end&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;is_end: {}, text: {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Key: {} Value: {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'value'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'hello!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

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

</description>
        <pubDate>Fri, 20 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Declare-Default-Values-for-Mutable-Types-in-Python/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Declare-Default-Values-for-Mutable-Types-in-Python/</guid>
      </item>
      
    
      
      <item>
        <title>Convert decimal to hexadecimal in the Python REPL</title>
        <description>&lt;p&gt;Convert a space-separated string of decimal integers into a space separated string of hexadecimal integers in the Python REPL.&lt;/p&gt;

&lt;p&gt;Starting string:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;137 60 228 95 213 195 161 98 210 106&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Make a list of integers:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;137 60 228 95 213 195 161 98 210 106&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Make a list of hex strings, without leading 0x characters:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Put the list back into a string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The final output is:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;89 3c e4 5f d5 c3 a1 62 d2 6a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One liner (yikes!):&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;137 60 228 95 213 195 161 98 210 106&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 13 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Convert-decimal-to-hexadecimal-in-the-Python-REPL/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Convert-decimal-to-hexadecimal-in-the-Python-REPL/</guid>
      </item>
      
    
      
      <item>
        <title>Initialize a C Array with Values</title>
        <description>&lt;p&gt;Initialize all members of a C array to the same value.&lt;/p&gt;

&lt;p&gt;For the GCC compiler, you can initialize an element to a particular value by specifying the array index and associated value.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&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;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&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;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Equivalent to:
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;42&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;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can also intialise a range of elements by using the format &lt;code class=&quot;highlighter-rouge&quot;&gt;[first ... last] = value&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a GNU extension.&lt;/p&gt;

&lt;h2 id=&quot;initialise-all-elements-to-the-same-value&quot;&gt;Initialise All Elements to the Same Value&lt;/h2&gt;
&lt;p&gt;The following complete example shows how this technique can be used to initialize all elements in an array to the same value:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#define N 5
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[ %d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, %d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; ]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c1&quot;&gt;// Incorrect method
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Output: [ 42, 0, 0, 0, 0 ]
&lt;/span&gt;	
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&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;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Output: [ 42, 42, 42, 42, 42 ]
&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html&quot;&gt;GCC Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 10 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Initialize-a-C-Array-with-Values/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Initialize-a-C-Array-with-Values/</guid>
      </item>
      
    
      
      <item>
        <title>Return a Result Type from the Main Function in Rust</title>
        <description>&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function in a Rust programme can return a &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt; type, which allows you to provide feedback to users as well as setting the appropriate exit codes for the programme.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParseIntError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParseIntError&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;this can't be parsed as a number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number_str&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;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;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The above programme prints &lt;code class=&quot;highlighter-rouge&quot;&gt;Error: ParseIntError { kind: InvalidDigit }&lt;/code&gt; to stdout.&lt;/p&gt;

&lt;p&gt;When the &lt;code class=&quot;highlighter-rouge&quot;&gt;parse::&amp;lt;i32&amp;gt;()&lt;/code&gt; method returns an error:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;match&lt;/code&gt; expression enters the &lt;code class=&quot;highlighter-rouge&quot;&gt;Err()&lt;/code&gt; branch&lt;/li&gt;
  &lt;li&gt;The error is passed into the branch&lt;/li&gt;
  &lt;li&gt;Finally another &lt;code class=&quot;highlighter-rouge&quot;&gt;Err()&lt;/code&gt; is returned - the error is output to &lt;code class=&quot;highlighter-rouge&quot;&gt;stderr&lt;/code&gt; and the function (and therefore the programme) is terminated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that in Linux the exit status of running this programme is 1, denoting that the command did not complete successfully.&lt;/p&gt;

&lt;p&gt;Here’s another example:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/**
* Contrived function, returns an error if the values are the same.
**/&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_largest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;equal values&quot;&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_largest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&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;c&quot;&gt;// If no error, use `number`.&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 04 Mar 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/03/Return-a-Result-Type-from-the-Main-Function-in-Rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/03/Return-a-Result-Type-from-the-Main-Function-in-Rust/</guid>
      </item>
      
    
      
      <item>
        <title>C++ Articles &amp; Resources</title>
        <description>&lt;p&gt;Collection of links to C++ articles that I think are worth reading.&lt;/p&gt;

&lt;h2 id=&quot;oop&quot;&gt;OOP&lt;/h2&gt;
&lt;p&gt;Express intentions (to users &amp;amp; compiler) with &lt;code class=&quot;highlighter-rouge&quot;&gt;override&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.fluentcpp.com/2020/02/21/virtual-final-and-override-in-cpp/&quot;&gt;Virtual, final and overrride in C++&lt;/a&gt;, Jonathan Boccara&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;declaring-classes&quot;&gt;Declaring Classes&lt;/h2&gt;
&lt;p&gt;Rationale for a particular way of declaring a class. Discusses the importance of the order of declarations, and consistency:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://howardhinnant.github.io/classdecl.html&quot;&gt;How I Declare My Class and Why&lt;/a&gt;, Howard E Hinnant&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;move-semantics&quot;&gt;Move Semantics&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=vLinb2fgkHk&amp;amp;feature=youtu.be&quot;&gt;Eveything you ever Wanted to Know About Move Semantics&lt;/a&gt;, Howard Hinnant&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 25 Feb 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/02/C++-Articles-&amp;-Resources/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/02/C++-Articles-&amp;-Resources/</guid>
      </item>
      
    
      
      <item>
        <title>Rust Vectors</title>
        <description>&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;vec!&lt;/code&gt; macro makes initializing vectors convenient:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;0x77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xd6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x7b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;0x3b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xc1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x8a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,];&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Initialize a vector of size n = 5 setting each element to &lt;code class=&quot;highlighter-rouge&quot;&gt;42&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// Note semicolon seperator&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Get an index within a for loop using &lt;code class=&quot;highlighter-rouge&quot;&gt;.iter().enumerate()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.enumerate&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;initialize-a-vector-with-values&quot;&gt;Initialize a Vector with Values&lt;/h2&gt;
&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;0x77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xd6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x7b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;0x3b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0xc1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x8a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0x97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,];&lt;/span&gt;
    
    &lt;span class=&quot;nf&quot;&gt;print_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;// Initialize a 5 element vector, each element set to 42&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;vec!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;print-vector&quot;&gt;Print Vector&lt;/h2&gt;
&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.enumerate&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;initialize-an-array&quot;&gt;Initialize an Array&lt;/h2&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// Array of 32 u8, each element set to 0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&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;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 02 Feb 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/02/Rust-Vectors/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/02/Rust-Vectors/</guid>
      </item>
      
    
      
      <item>
        <title>Passing by Reference in Rust</title>
        <description>&lt;p&gt;Example of passing arguments by reference in Rust:&lt;/p&gt;

&lt;div class=&quot;language-rs highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c&quot;&gt;// Define a mutable variable and a reference to it&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_main_ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;// Prints the return value of `increment_value`, original variable unchanged&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;increment_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_main_ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// &quot;101&quot;&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;n_main = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// &quot;n_main = 100&quot;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;// This function receives a mutable reference, and changes the original value.&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;amend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;n_main = {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// &quot;n_main = 199&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;// Accepts a mutable reference, changes the value it refers to, no return value&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;amend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_inc_ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_inc_ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;99&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;c&quot;&gt;// Accepts a reference, does not mutate it, returns same type as the passed-in reference&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;increment_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_inc_ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;n_inc_ref&lt;/span&gt; &lt;span class=&quot;o&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 02 Feb 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/02/Passing-by-Reference-in-Rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/02/Passing-by-Reference-in-Rust/</guid>
      </item>
      
    
      
      <item>
        <title>Sync Forked Repo With Upstream</title>
        <description>&lt;p&gt;Once you’ve forked and cloned a repo the following describes how to sync the local fork with the upstream remote.&lt;/p&gt;

&lt;h2 id=&quot;configure-remote&quot;&gt;Configure Remote&lt;/h2&gt;
&lt;p&gt;Check current remotes:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will probably output &lt;code class=&quot;highlighter-rouge&quot;&gt;origin&lt;/code&gt;, denoting that your repo has a single remote.&lt;/p&gt;

&lt;p&gt;Configure a Git remote for the upstream (original) repo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote add upstream https://github.com/original-project/original-project.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
origin
upstream
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;sync-local-fork-with-upstream&quot;&gt;Sync Local Fork with Upstream&lt;/h2&gt;
&lt;p&gt;There are now three repositories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;local&lt;/li&gt;
  &lt;li&gt;origin (GitHub, Bitbucket etc)&lt;/li&gt;
  &lt;li&gt;upstream (The original repo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sync from upstream to local, then push changes to origin:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# fetch changes&lt;/span&gt;
git fetch upstream

&lt;span class=&quot;c&quot;&gt;# switch to master branch&lt;/span&gt;
git checkout master

&lt;span class=&quot;c&quot;&gt;# Merge changes from upstream into master&lt;/span&gt;
git merge upstream/master

&lt;span class=&quot;c&quot;&gt;# Push local changes to origin&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 23 Jan 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/01/Sync-Forked-Repo-With-Upstream/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/01/Sync-Forked-Repo-With-Upstream/</guid>
      </item>
      
    
      
      <item>
        <title>Bitcoin RPC Through SSH Tunnel</title>
        <description>&lt;p&gt;Bitcoin Core functions as a HTTP JSON-RPC server by means of the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; programme. This means that Bitcoin Core can be controlled remotely by means of HTTP requests.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.jsonrpc.org/specification_v1&quot;&gt;JSON-RPC&lt;/a&gt; is a lightweight remote procedure call protocol. It involves a client sending requests in JSON format to a server. The server (in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt;) executes the required function and sends a serialized JSON object back to the client as a response.&lt;/p&gt;

&lt;p&gt;Authentication in &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcond&lt;/code&gt; is by means of basic HTTP authentication. A username/password combination is set on the server, and requests must supply this data. Because the connection is not HTTPS/TLS, the username/password are exposed in the request. This isn’t a problem if the connection is made on the same computer that is running &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; but if the client accesses the server over the network, it opens a security vulnerability.&lt;/p&gt;

&lt;p&gt;SSH tunneling fixes this by sending all data over an encrypted channel.&lt;/p&gt;

&lt;h2 id=&quot;why-use-an-ssh-tunnel&quot;&gt;Why Use an SSH Tunnel?&lt;/h2&gt;
&lt;p&gt;SSH is a standard for secure remote login and file transfer over untrusted networks. SSH can be set up to use port forwarding to tunnel any TCP/IP port over SSH. Because data flows over an SSH connection, it is encrypted in transit. This makes SSH tunneling an obvious choice when sending and receiving sensitive data.&lt;/p&gt;

&lt;p&gt;This example involves connecting to a remote &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; RPC-JSON server over an SSH tunnel. The application does not allow HTTPS connection. Without SSH tunneling (or similar encrypted channel) sensitive information such as authentication data, addresses and Bitcoin amounts would be sent over a public network in cleartext.&lt;/p&gt;

&lt;p&gt;An SSH tunnel can be set up to forward traffic sent to a specified port on localhost to a specified port on a remote host. Forwarding a port from the client machine to the server machine in this way is known as &lt;strong&gt;Local Forwarding&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-json-rpc-server&quot;&gt;Setting Up the JSON-RPC Server&lt;/h2&gt;
&lt;p&gt;You can either pass command-line options when starting &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; to enable the RPC interface and control other necessary settings, or you can add configuration data in a config file.&lt;/p&gt;

&lt;p&gt;The config file approach is probably the most practical, and is the method covered in this article.&lt;/p&gt;

&lt;p&gt;When started, &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; looks for a configuration file named &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin.conf&lt;/code&gt; in the bitcoin data directory (under Linux, this is &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bitcoin&lt;/code&gt; by default). You’ll need to specify:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The IP/IP range that is allowed access&lt;/li&gt;
  &lt;li&gt;Authentication credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;allowrestrict-ip-address&quot;&gt;Allow/Restrict IP Address&lt;/h2&gt;
&lt;p&gt;By default, &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; only allows RPC connections from localhost. You can ease this restriction by specifying an IP address in the &lt;code class=&quot;highlighter-rouge&quot;&gt;rpcallowip&lt;/code&gt; field in the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bitcoin/bitcoin.conf&lt;/code&gt; configuration file.&lt;/p&gt;

&lt;p&gt;Example &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin.conf&lt;/code&gt; allowing RPC access from the &lt;code class=&quot;highlighter-rouge&quot;&gt;192.168.122&lt;/code&gt; subnet to the &lt;code class=&quot;highlighter-rouge&quot;&gt;regtest&lt;/code&gt; network:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# /path/to/bitcoin.conf&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# These settings apply to the regtest network only&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;regtest]
&lt;span class=&quot;nv&quot;&gt;rpcbind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0.0.0.0
&lt;span class=&quot;nv&quot;&gt;rpcallowip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;192.168.122.0/24 &lt;span class=&quot;c&quot;&gt;# Allow access fromm the 192.168.122 subnet&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1 &lt;span class=&quot;c&quot;&gt;# Tells the bitcoin server to accept JSON-RPC commands&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;rpcuser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;yourusername &lt;span class=&quot;c&quot;&gt;# Required for the JSON-RPC API&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;rpcpassword&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;yourpassword &lt;span class=&quot;c&quot;&gt;# Required&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The example shows a config block for the regtest network. To set up access for mainnet, you would provide a similar configuration block for &lt;code class=&quot;highlighter-rouge&quot;&gt;[main]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;security-of-the-json-rpc-server&quot;&gt;Security of the JSON-RPC Server&lt;/h2&gt;
&lt;p&gt;The JSON-RPC server requires basic HTTP authentication. For example, to send a request using &lt;code class=&quot;highlighter-rouge&quot;&gt;curl&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl --user alice:password123 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--data-binary &lt;span class=&quot;s1&quot;&gt;'{&quot;jsonrpc&quot;:&quot;1.0&quot;,&quot;id&quot;:&quot;curltext&quot;,&quot;method&quot;:&quot;listunspent&quot;,&quot;params&quot;:[]}'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
-H &lt;span class=&quot;s1&quot;&gt;'content-type:text/plain;'&lt;/span&gt; http://192.168.122.18:18443/ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the username is &lt;code class=&quot;highlighter-rouge&quot;&gt;alice&lt;/code&gt; and the (obviously inadequate) password is ‘password123’.&lt;/p&gt;

&lt;p&gt;The request is made to &lt;code class=&quot;highlighter-rouge&quot;&gt;http://192.168.122.18:18443&lt;/code&gt; - a virtual machine that shares a network with the client machine making the request. In this case, the local network IP address of the client machine is &lt;code class=&quot;highlighter-rouge&quot;&gt;192.168.122.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The request sends the method &lt;code class=&quot;highlighter-rouge&quot;&gt;listunspent&lt;/code&gt;, which is processed by Bitcoin Core and the result returned as a JSON object.&lt;/p&gt;

&lt;h3 id=&quot;authentication-data-is-sent-in-plaintext&quot;&gt;Authentication Data is Sent in Plaintext&lt;/h3&gt;
&lt;p&gt;Authentication data (user name and password) is sent as base 64 encoded plaintext. This example shows the HTTP header packets including the authorization data.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-data&quot;&gt;0000:  504f 5354 202f 2048 5454 502f 312e 310d  POST / HTTP/1.1.
0010:  0a48 6f73 743a 2031 3932 2e31 3638 2e31  .Host: 192.168.1
0020:  3232 2e31 383a 3138 3434 330d 0a41 7574  22.18:18443..Aut
0030:  686f 7269 7a61 7469 6f6e 3a20 4261 7369  horization: Basi
0040:  6320 5957 7870 5932 5536 6347 467a 6333  c YWxpY2U6cGFzc3
0050:  6476 636d 5178 4d6a 4d3d 0d0a 5573 6572  dvcmQxMjM=..User
0060:  2d41 6765 6e74 3a20 6375 726c 2f37 2e34  -Agent: curl/7.4
0070:  372e 300d 0a41 6363 6570 743a 202a 2f2a  7.0..Accept: */*
0080:  0d0a 636f 6e74 656e 742d 7479 7065 3a74  ..content-type:t
0090:  6578 742f 706c 6169 6e3b 0d0a 436f 6e74  ext/plain;..Cont
00a0:  656e 742d 4c65 6e67 7468 3a20 3638 0d0a  ent-Length: 68..
00b0:  0d0a                                             ..

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These packets were captured on the server hosting &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt;, but they show how the data is transmitted over the network.&lt;/p&gt;

&lt;p&gt;Note that in the above block &lt;code class=&quot;highlighter-rouge&quot;&gt;YWxpY2U6cGFzc3dvcmQxMjM=&lt;/code&gt; represents the base64 encoded user:password combination - in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;alice:password123&lt;/code&gt;. This is &lt;strong&gt;not encrypted&lt;/strong&gt; - it’s simply a base64 representation of the ASCII characters. See for yourself by &lt;a href=&quot;https://www.base64decode.net/&quot;&gt;decoding here&lt;/a&gt;. Obviously this is a security vulnerability - an eavesdropper can easily determine the user name and password.&lt;/p&gt;

&lt;p&gt;In the case of basic HTTP authentication like this, the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication&quot;&gt;connection is not secure&lt;/a&gt; unless the exchange takes place over HTTPS(TLS).&lt;/p&gt;

&lt;p&gt;The Bitcoin RPC API does not allow connection via SSL - &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/d6a92dd0ea42ec64f15b81843b4db62c7b186bdb/doc/release-notes.md#ssl-support-for-rpc-dropped&quot;&gt;this functionality was dropped in 2015&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, we can easily fix this by using an SSH Tunnel to connect.&lt;/p&gt;

&lt;h2 id=&quot;ssh-tunnel&quot;&gt;SSH Tunnel&lt;/h2&gt;
&lt;p&gt;If the computer hosting &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; is set up to communicate with a client machine by means of SSH, it is pretty straightforward to set up an SSH tunnel.&lt;/p&gt;

&lt;p&gt;Set up SSH local port forwarding on the client machine that will access the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; server - i.e. the computer that will send HTTP requests to the RPC server:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh -v -fNL 5555:192.168.122.18:18443 remote_user@192.168.122.18
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;To send traffic through the ssh tunnel, you now use the &lt;code class=&quot;highlighter-rouge&quot;&gt;127.0.0.1:5555&lt;/code&gt; host:port combination.&lt;/p&gt;

&lt;p&gt;The same data shown above now results in the following packet - approximately, since the data is encrypted and there is no way to tell which bytes constitute the HTTP header:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;20:43:28.404868 IP _gateway.44348 &amp;gt; donnager.ssh: Flags [P.], seq 100:376, ack 45, win 296, options [nop,nop,TS val 5081969 ecr 985853552], length 276
0000:  4510 0148 828f 4000 4006 41ac c0a8 7a01  E..H..@.@.A...z.
0010:  c0a8 7a12 ad3c 0016 af75 982e c79e cd40  ..z..&amp;lt;...u.....@
0020:  8018 0128 f86f 0000 0101 080a 004d 8b71  ...(.o.......M.q
0030:  3ac2 ee70 fb68 ceb4 aa74 80d3 aef4 f56b  :..p.h...t.....k
0040:  3794 e39d 9468 888a 7aa4 44d4 377e b1b3  7....h..z.D.7~..
0050:  9a87 f91a d4eb 9650 cb7a 2906 ae71 fca8  .......P.z)..q..
0060:  bd0b c8ec bbe6 01f0 42d1 6c11 e560 ddae  ........B.l..`..
0070:  817e 2fa0 df1c 6f70 ca19 b5d9 bb8e 0dca  .~/...op........
0080:  f5ff 0d3e ab69 a43b 1cc6 cfb7 e8f2 1bca  ...&amp;gt;.i.;........
0090:  cae2 14c4 85a7 f06f 33be f097 f904 713b  .......o3.....q;
00a0:  13cf a482 19d4 b3a2 6ede 887d 2749 b897  ........n..}'I..
00b0:  ed27 3deb d8a2 a60e 96ee 074f 085f d134  .'=........O._.4
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;python-example&quot;&gt;Python Example&lt;/h2&gt;
&lt;p&gt;It is fairly straightforward to wrap the SSH tunnel and request process in a Python programme, as this basic example shows:&lt;/p&gt;

&lt;h3 id=&quot;ssh-tunnel-1&quot;&gt;SSH Tunnel&lt;/h3&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# ssh_tunnel.py&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;subprocess&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;threading&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SSHTunnel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_port&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_port&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_user&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_host&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;daemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subprocess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'ssh'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'-N'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'-L'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;':'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;':'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'@'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_host&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ssh tunnel setup failed.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id=&quot;configuration-data&quot;&gt;Configuration Data&lt;/h3&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&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;&quot;local_port&quot;&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;5432&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;nt&quot;&gt;&quot;remote_port&quot;&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;18443&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;nt&quot;&gt;&quot;remote_user&quot;&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;s2&quot;&gt;&quot;alice&quot;&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;nt&quot;&gt;&quot;remote_host&quot;&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;s2&quot;&gt;&quot;111.222.43.232&quot;&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;nt&quot;&gt;&quot;rpc_user&quot;&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;s2&quot;&gt;&quot;alice&quot;&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;nt&quot;&gt;&quot;rpc_password&quot;&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;s2&quot;&gt;&quot;password123&quot;&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;request-through-the-tunnel&quot;&gt;Request Through the Tunnel&lt;/h3&gt;
&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ssh_tunnel&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SSHTunnel&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pygments&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lexers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatters&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tunnel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SSHTunnel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;local_port&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;remote_port&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;remote_user&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;remote_host&quot;&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;n&quot;&gt;tunnel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&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;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'content-type'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'text/plain;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'{&quot;jsonrpc&quot;:&quot;1.0&quot;,&quot;id&quot;:&quot;curltext&quot;,&quot;method&quot;:&quot;listunspent&quot;,&quot;params&quot;:[]}'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;http://127.0.0.1:{}/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;local_port&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;rpc_user&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;rpc_password&quot;&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;n&quot;&gt;response_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;my_vals&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'txid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'txid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'amount'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'amount'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'address'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'address'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'vout'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'vout'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'result'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_vals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lexers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JsonLexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TerminalFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Please pass a path to a config file.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/csknk/ssh-tunnel-bitcoin&quot;&gt;GitHub repo for this example&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;references--resources&quot;&gt;References &amp;amp; Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.jsonrpc.org/specification_v1&quot;&gt;JSON-RPC specifications&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.json.org/json-en.html&quot;&gt;JSON Reference&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.ietf.org/html/rfc7617&quot;&gt;Basic HTTP Authentication&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/Running_Bitcoin&quot;&gt;Bitcoin Wiki: configuration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ssh.com/ssh/tunneling&quot;&gt;SSH Tunneling&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.golinuxcloud.com/configure-ssh-port-forwarding-tunneling-linux/&quot;&gt;Configuring SSH port forwarding on Linux&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitcoincore.org/en/releases/0.17.0/#configuration-sections-for-testnet-and-regtest&quot;&gt;Bitcoin bitcoin.conf Config sections&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/ssh-tunnel-bitcoin&quot;&gt;Basic example, SSH Tunnel to Bitcoin with Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 18 Jan 2020 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2020/01/Bitcoin-RPC-Through-SSH-Tunnel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2020/01/Bitcoin-RPC-Through-SSH-Tunnel/</guid>
      </item>
      
    
      
      <item>
        <title>Fast Modular Exponentiation</title>
        <description>&lt;p&gt;Modular exponentiation is used in public key cryptography.&lt;/p&gt;

&lt;p&gt;It involves computing &lt;em&gt;b&lt;/em&gt; to the power &lt;em&gt;e&lt;/em&gt; (mod &lt;em&gt;m&lt;/em&gt;):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;c&lt;/em&gt; ← &lt;em&gt;b&lt;/em&gt;&lt;sup&gt;e&lt;/sup&gt; (mod &lt;em&gt;m&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;You could brute-force this problem by multiplying &lt;em&gt;b&lt;/em&gt; by itself &lt;em&gt;e&lt;/em&gt; - 1 times and taking the answer mod &lt;em&gt;m&lt;/em&gt;, but it is important to have &lt;strong&gt;fast&lt;/strong&gt; (efficient) algorithms for this process to have any practical application.&lt;/p&gt;

&lt;p&gt;In cryptography, the numbers involved are usually very large. Without an efficient algorithm, the process would take too long.&lt;/p&gt;

&lt;p&gt;This article is educational - it is a summary of what I have learned about the process of modular exponentiation, with a few code implementations of a possible algorithm rather than a presentation of the most efficient methods.&lt;/p&gt;

&lt;h2 id=&quot;naive-exponentiation&quot;&gt;Naive Exponentiation&lt;/h2&gt;
&lt;p&gt;THe most basic approach would be to multiply &lt;em&gt;b&lt;/em&gt; by itself &lt;em&gt;e&lt;/em&gt; - 1 times, and performing floor division on the result to obtain the result modulo &lt;em&gt;m&lt;/em&gt; (which will be the remainder or residue of floor division of the result by the modulus). There are a few problems with this approach:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If &lt;em&gt;b&lt;/em&gt; and &lt;em&gt;e&lt;/em&gt; are large numbers, &lt;em&gt;b&lt;/em&gt;&lt;sup&gt;e&lt;/sup&gt; will be enormous - which causes problems representing the resultant data as a native type in many languages/systems.&lt;/li&gt;
  &lt;li&gt;If &lt;em&gt;b&lt;/em&gt; and &lt;em&gt;e&lt;/em&gt; are large, a lot of multiplications are required. The universe might not last long enough for us to carry out the computation…&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;slightly-less-naive-approach&quot;&gt;Slightly Less Naive Approach&lt;/h2&gt;
&lt;p&gt;For multiplication (mod &lt;em&gt;m&lt;/em&gt;) congruence is maintained. In other words:&lt;/p&gt;

&lt;p&gt;if a ≡ x (mod m) then a ∙ k ≡ x (mod m)&lt;/p&gt;

&lt;p&gt;It follows that if we’re just concerned with congruences (i.e. the residue mod m), multiplying the congruences provides the same result as multiplying the factors and then taking the result modulo m:&lt;/p&gt;

&lt;p&gt;If a ∙ b ≡ x (mod m), then a (mod m) ∙ a (mod m) ≡ x (mod m)&lt;/p&gt;

&lt;p&gt;In terms of an exponentiation algorithm, multiplying the result modulo &lt;em&gt;m&lt;/em&gt; at each step leads to much smaller numbers which spares computational resources.&lt;/p&gt;

&lt;h3 id=&quot;slightly-better-algorithm&quot;&gt;Slightly Better Algorithm&lt;/h3&gt;
&lt;p&gt;For &lt;em&gt;c&lt;/em&gt; ← &lt;em&gt;b&lt;/em&gt;&lt;sup&gt;e&lt;/sup&gt; (mod &lt;em&gt;m&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Start with 1, multiply by &lt;em&gt;b&lt;/em&gt;, take the result mod(&lt;em&gt;m&lt;/em&gt;), repeat &lt;em&gt;e&lt;/em&gt; times.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Start with &lt;em&gt;c&lt;/em&gt; ← 1&lt;/li&gt;
  &lt;li&gt;Repeat &lt;em&gt;e&lt;/em&gt; times: &lt;em&gt;c&lt;/em&gt; ← &lt;em&gt;c&lt;/em&gt; ∙ &lt;em&gt;b&lt;/em&gt; mod &lt;em&gt;m&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;exponent-is-a-power-of-two&quot;&gt;Exponent is a Power of Two&lt;/h2&gt;
&lt;p&gt;If &lt;em&gt;c&lt;/em&gt; ← &lt;em&gt;b&lt;/em&gt;&lt;sup&gt;e&lt;/sup&gt; (mod &lt;em&gt;m&lt;/em&gt;) and&lt;/p&gt;

&lt;p&gt;&lt;em&gt;e&lt;/em&gt; = 2&lt;sup&gt;k&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;We can compute &lt;em&gt;c&lt;/em&gt; using the “squares” method - this allows for fast computation of large positive integer powers of a number.&lt;/p&gt;

&lt;p&gt;From rules of indices:&lt;/p&gt;

&lt;p&gt;(b&lt;sup&gt;e&lt;/sup&gt;)&lt;sup&gt;f&lt;/sup&gt; = b&lt;sup&gt;ef&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;For example, this allows a⁸, can be represented as ((a²)²)².&lt;/p&gt;

&lt;p&gt;If you calculate a⁸ naively:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;a⁸ = a ∙ a ∙ a ∙ a ∙ a ∙ a ∙ a ∙ a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;…7 multiplications are required (the exponent - 1).&lt;/p&gt;

&lt;p&gt;Alternatively, computing &lt;code class=&quot;highlighter-rouge&quot;&gt;a⁸&lt;/code&gt; as &lt;code class=&quot;highlighter-rouge&quot;&gt;((a²)²)²&lt;/code&gt; requires three multiplications:&lt;/p&gt;

&lt;p&gt;a ∙ a = s₁
s₁ ∙ s₁ = s₂, where s₂ is equivalent to (a²)²
s₂ ∙ s₂ = s₃, where s₃ is equivalent to ((a²)²)²&lt;/p&gt;

&lt;p&gt;In this way, &lt;code class=&quot;highlighter-rouge&quot;&gt;aⁿ&lt;/code&gt; requires no more than 2 log₂(&lt;em&gt;e&lt;/em&gt;) multiplications, where &lt;em&gt;e&lt;/em&gt; is the exponent.&lt;/p&gt;

&lt;p&gt;So long as our exponent is a power of 2, and we multiply congruences at each stage, we have an efficient algorithm that can be converted to code:&lt;/p&gt;

&lt;h3 id=&quot;example-code-exponent-is-a-power-of-2&quot;&gt;Example Code: Exponent is a Power of 2&lt;/h3&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;exponent_power_of_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e_power2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&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;n&quot;&gt;e_power2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;exponent-is-not-necessarily-a-power-of-two&quot;&gt;Exponent is Not Necessarily a Power of Two&lt;/h2&gt;
&lt;p&gt;The previous algorithm gets us on the right track, but it has a major limitation - it only works if the exponent is a power of two.&lt;/p&gt;

&lt;p&gt;We can however take the principle and generalise it so that it works for any number.&lt;/p&gt;

&lt;p&gt;The idea is to take any number represented as the summation of powers of two - which as luck would have it, is exactly the way that modern computers represent numbers - and to create a running total of the required squares.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;a&lt;sup&gt;11&lt;/sup&gt; = a&lt;sup&gt;8&lt;/sup&gt; ∙ a&lt;sup&gt;2&lt;/sup&gt; ∙ a&lt;sup&gt;1&lt;sup&gt;&lt;/sup&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;…Notice that 8, 2 and one are powers of 2 (3, 1 and 0 respectively).&lt;/p&gt;

&lt;p&gt;We can get the answer by working through each power of two up to the maximum possible given the size of e, squaring the base at each stage and only adding the squares to the result if the given power of two is a factor in the exponent.&lt;/p&gt;

&lt;h3 id=&quot;algorithm&quot;&gt;Algorithm&lt;/h3&gt;
&lt;p&gt;Given a base &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;, an exponent &lt;code class=&quot;highlighter-rouge&quot;&gt;e&lt;/code&gt; and modulo &lt;code class=&quot;highlighter-rouge&quot;&gt;m&lt;/code&gt;, compute b&lt;sup&gt;e&lt;/sup&gt; (mod m):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create an integer (or long) variable called &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; and set this result equal to 1.&lt;/li&gt;
  &lt;li&gt;Check the least significant bit (2⁰) of the exponent e. If it is 1, set &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; equal to &lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Check each bit in the exponent by iteratively bitshifting and masking against 1 - this checks each position in order, starting from the second-least-significant bit (we have already considered the least most significant bit in stage 2.&lt;/li&gt;
  &lt;li&gt;Start a loop&lt;/li&gt;
  &lt;li&gt;At each iteration, set &lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt; equal to the value of the previous &lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt; squared, modulo &lt;code class=&quot;highlighter-rouge&quot;&gt;m&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;At each stage, if the LSB of &lt;code class=&quot;highlighter-rouge&quot;&gt;e&lt;/code&gt; is set, set &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; equal to the product of the previous &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; and the current &lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt; (which is the previous base squared, as described in stage 3), all modulo &lt;code class=&quot;highlighter-rouge&quot;&gt;m&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;When the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;e&lt;/code&gt; is NULL, end the loop&lt;/li&gt;
  &lt;li&gt;The value of result is the product of all b to the power of two for all powers of two that constitute the exponent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In summary, set the result to be 1. Starting from the least significant bit of the exponent, iteratively check each bit - which denotes that the particular power of two is a component of the exponent. Square the base modulo m at each stage. If the exponent bit is set, multiply the base with the current result, modulo m. The final result is the base raised to the exponent mod m - the product of a set of base raised to exponents that constitute the original exponent broken into powers of two.&lt;/p&gt;

&lt;h2 id=&quot;example-code&quot;&gt;Example Code&lt;/h2&gt;
&lt;p&gt;Examples applying the above algorithm in C and Python are shown below:&lt;/p&gt;

&lt;h3 id=&quot;example-c&quot;&gt;Example: C&lt;/h3&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// See: https://github.com/DavidCWebs/input-integer-C for integer inputfunction
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &quot;integer-input.h&quot;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fastExp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;if&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;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;while&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;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;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;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&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;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Compute b to the power e modulo m&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter b:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;getIntegerFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter e:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;getIntegerFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter m:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;getIntegerFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d to the power %d ≡ %d (mod%d)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fastExp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;example-python&quot;&gt;Example: Python&lt;/h3&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fast_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&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;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter b:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter e:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter m:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fast_exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{} ^ {} ≡ {} (mod {})&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/fast-modular-exponentiation&quot;&gt;Code examples, GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.khanacademy.org/computing/computer-science/cryptography#modarithmetic&quot;&gt;Modular Arithmetic, Khan Academy&lt;/a&gt;, with practice quizzes&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=DtV4Fwvn0e8&quot;&gt;Intro to modular exponentiation&lt;/a&gt;, You Tube, Mark’s Education Tutorials&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tTuWmcikE0Q&quot;&gt;Modular Exponentiation Made Easy&lt;/a&gt;, Randall Heyman YouTube&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 12 Dec 2019 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2019/12/Fast-Modular-Exponentiation/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/12/Fast-Modular-Exponentiation/</guid>
      </item>
      
    
      
      <item>
        <title>Double Negation Operator Convert to Boolean in C</title>
        <description>&lt;p&gt;In C and C++ the double negation operator can be (and often is) used to convert a value to a boolean.&lt;/p&gt;

&lt;p&gt;Simply put, if &lt;code class=&quot;highlighter-rouge&quot;&gt;int x = 42&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;!!x&lt;/code&gt; evaluates to 1. If &lt;code class=&quot;highlighter-rouge&quot;&gt;x = 0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;!!x&lt;/code&gt; evaluates to 0.&lt;/p&gt;

&lt;p&gt;You could argue that it is not readable, but as of the current date I counted more than 5000 instances of this idiom in the Linux kernel. For this reason alone it’s worth being aware of it.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Following statements are equivalent:
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Output: &quot;x is 42, which is boolean 1.&quot;
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Following statements are equivalent:
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x is %d, which is boolean %d.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;//Output: &quot;x is 0, which is boolean 0.&quot;
&lt;/span&gt;	
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</description>
        <pubDate>Tue, 29 Oct 2019 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2019/10/Double-Negation-Operator-Convert-to-Boolean-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/10/Double-Negation-Operator-Convert-to-Boolean-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Sync Forked Repo With Upstream</title>
        <description>&lt;p&gt;If you have forked a Git repository, you’ll need to sync it with the upstream repo so that your changes are applied to the current version of the project.&lt;/p&gt;

&lt;h2 id=&quot;configure-remote&quot;&gt;Configure Remote&lt;/h2&gt;
&lt;p&gt;Check current remotes:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will probably output &lt;code class=&quot;highlighter-rouge&quot;&gt;origin&lt;/code&gt;, denoting that your repo has a single remote.&lt;/p&gt;

&lt;p&gt;Configure a Git remote for the upstream (original) repo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote add upstream https://github.com/original-project/original-project.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git remote

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
origin
upstream
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;sync-local-fork-with-upstream&quot;&gt;Sync Local Fork with Upstream&lt;/h2&gt;
&lt;p&gt;There are now three repositories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;local&lt;/li&gt;
  &lt;li&gt;origin (GitHub, Bitbucket etc)&lt;/li&gt;
  &lt;li&gt;upstream (The original repo)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sync from upstream to local, then push changes to origin:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# fetch changes&lt;/span&gt;
git fetch upstream

&lt;span class=&quot;c&quot;&gt;# switch to master branch&lt;/span&gt;
git checkout master

&lt;span class=&quot;c&quot;&gt;# Merge changes from upstream into master&lt;/span&gt;
git merge upstream/master

&lt;span class=&quot;c&quot;&gt;# Push local changes to origin&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 04 Oct 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/10/Sync-Forked-Repo-With-Upstream/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/10/Sync-Forked-Repo-With-Upstream/</guid>
      </item>
      
    
      
      <item>
        <title>Compute Bitcoin Merkle Root</title>
        <description>&lt;p&gt;Merkle trees are an efficient way to verify that an element is in a set, without having to store the full set.&lt;/p&gt;

&lt;p&gt;The leaf nodes (lowest level nodes) of the Merkle tree are made up of hashes of individual data members of the set. In the case of Bitcoin, individual data members are made up from transaction ids (TXIDs). TXIDs are the result of SHA256 hashing the bytes in a raw transaction twice.&lt;/p&gt;

&lt;p&gt;Adjacent leaves are concatenated pairwise, and the hash of the concatenation constitutes the node’s parent.&lt;/p&gt;

&lt;p&gt;Parent nodes are concatenated and hashed in a similar way to generate another level of parent nodes. This process is repeated until a single hash remains - the &lt;strong&gt;Merkle root&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each non-leaf node of a merkle tree is a hash of the concatenation of it’s immediate children. The leaves of the tree are the elements of the set to which the Merkle tree proves membership.&lt;/p&gt;

&lt;h2 id=&quot;merkle-trees-as-implemented-by-bitcoin&quot;&gt;Merkle Trees as Implemented By Bitcoin&lt;/h2&gt;
&lt;p&gt;In the case of Bitcoin, the leaves of the Merkle tree are the transaction identifiers (the hash of a raw transaction).&lt;/p&gt;

&lt;p&gt;If there are an odd number of nodes at any level, the final node is concatenated with itself.  Parent nodes are in turn concatenated in pairs and hashed, with the process repeated until a single Merkle hash remains - the Merkle root.&lt;/p&gt;

&lt;p&gt;The Merkle root is stored in a block header, where it serves to make transactions tamper-proof - if a transaction is changed, the Merkle root would be thrown off. Because the hash of each block is included in subsequent blocks, the tamper would be immediately evident and the block with the tampered transaction would not be accepted as valid by the Bitcoin consensus rules.&lt;/p&gt;

&lt;p&gt;To verify a transaction - check that a transaction is in a valid block - you just need the hashes of Merkle branch to compute the Merkle root, not the entire set of transactions in the block.&lt;/p&gt;

&lt;h2 id=&quot;flaw-in-bitcoin-implementation-of-merkle-trees&quot;&gt;Flaw in Bitcoin Implementation of Merkle Trees&lt;/h2&gt;
&lt;p&gt;As can be seen in &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/master/src/consensus/merkle.cpp#L8&quot;&gt;this comment&lt;/a&gt; in the Bitcoin Core codebase, and described comprehensively &lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0098.mediawiki&quot;&gt;in BIP 98&lt;/a&gt;, there is a flaw in the Bicoin implementation of Bitcoin’s Merkle tree algorithm relating to duplicate txids.&lt;/p&gt;

&lt;p&gt;The flaw is caused by the duplication of the last node in the case of levels that have an odd number of nodes - a practice which is non-standard for Merkle trees.&lt;/p&gt;

&lt;h2 id=&quot;c-implementation&quot;&gt;C++ Implementation&lt;/h2&gt;

&lt;p&gt;Compute a Merkle root from a set of transaction IDs (txid) expressed as hexadecimal strings. The code shown is from the file &lt;a href=&quot;https://github.com/csknk/compute-bitcoin-merkle-root/blob/master/bitcoin.cpp&quot;&gt;bitcoin.cpp&lt;/a&gt; in the accompanying repo:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * Compute the Merkle root 
 * */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;merkleRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&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;k&quot;&gt;throw&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;c1&quot;&gt;// Loop until the txid container has been reduced to a single element - the Merkle root
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;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;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// If odd number, add the last element to end of vector.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Note that this is required at every level of the tree.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&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;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;back&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;n&quot;&gt;Bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      
      &lt;span class=&quot;c1&quot;&gt;// Concatenate this element and the following adjacent element
&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;begin&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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
      
      &lt;span class=&quot;c1&quot;&gt;// Hash the concatenated elements, save into `result` container
&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;doubleSHA256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;// `tmp` is a container holding the results of concatenating &amp;amp; hashing
&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&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;c1&quot;&gt;// Set txids to reflect the reduction in elements from this round of concatenation/hashing
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;txids&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&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;c1&quot;&gt;// At this point, `txids` should be a container with a single element.
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txids&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;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this example, the &lt;code class=&quot;highlighter-rouge&quot;&gt;merkleRoot&lt;/code&gt; function receives two parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&amp;lt;Bytes&amp;gt; txids&lt;/code&gt; - where &lt;code class=&quot;highlighter-rouge&quot;&gt;Bytes&lt;/code&gt; is an alias for &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&amp;lt;uint8_t&amp;gt;&lt;/code&gt;, a collection of byte objects.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Bytes&amp;amp; result&lt;/code&gt; - A &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;uint8_t&amp;gt;&lt;/code&gt; objects, passed by reference to receive the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;
&lt;p&gt;You try out the code above by cloning the accompanying &lt;a href=&quot;https://github.com/csknk/compute-bitcoin-merkle-root&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;get-txids-for-a-block-using-bitcoin-cli&quot;&gt;Get TXIDs for a Block Using bitcoin-cli&lt;/h2&gt;
&lt;p&gt;You can use &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-cli&lt;/code&gt; to get the transactions from a &lt;a href=&quot;https://www.blockchain.com/btc/block/00000000000000000002f5b1c49b9ddf5537d418b6c5b835172b3987a09a4b13&quot;&gt;sample block&lt;/a&gt; and save these as a manifest file:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Write transaction ids for block&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 00000000000000000002f5b1c49b9ddf5537d418b6c5b835172b3987a09a4b13&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to /tmp/manifest&lt;/span&gt;
bitcoind --daemon &lt;span class=&quot;c&quot;&gt;# bitcoind must be running&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Fetch block and process results with `jq` to obtain a file comprised of `txid` hashes for all&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# transactions in the block, each on a separate line. The file `/tmp/txid.manifest` can then be&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# used as input to the programme via input redirection:&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00000000000000000002f5b1c49b9ddf5537d418b6c5b835172b3987a09a4b13
bitcoin-cli getblock &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; | jq -r &lt;span class=&quot;s1&quot;&gt;'.tx[]'&lt;/span&gt; &amp;gt; /tmp/txid.manifest
bitcoin-cli stop
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is useful for testing Merkle tree root computation - you can check the result of your implementation with the Merkle root computed by Bitcoin Core:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# set ${block} as above&lt;/span&gt;
bitcoin-cli getblock &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; | jq -r &lt;span class=&quot;s1&quot;&gt;'.merkleroot'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you don’t have &lt;code class=&quot;highlighter-rouge&quot;&gt;jq&lt;/code&gt; installed, you can achieve roughly the same result with standard UNIX tools like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bitcoin-cli getblock &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; | grep merkleroot | awk &lt;span class=&quot;s1&quot;&gt;'{print substr($2,2, length($2) - 3)}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/compute-bitcoin-merkle-root&quot;&gt;GitHub repo partnering this article&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/master/src/consensus/merkle.cpp&quot;&gt;Bitcoin core Merkle root computation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/csknk/compute-bitcoin-merkle-root/blob/master/bitcoin.cpp&quot;&gt;Merkle root computation, partner repo&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Merkle_treea&quot;&gt;Merkle Trees&lt;/a&gt; (Wikipedia)&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 01 Sep 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/09/compute-bitcoin-merkle-root/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/09/compute-bitcoin-merkle-root/</guid>
      </item>
      
    
      
      <item>
        <title>Convert integer to array of char bytes</title>
        <description>&lt;p&gt;To convert an integer to an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;, you can bitmask against the integer in a loop to get the value for each byte.&lt;/p&gt;

&lt;h2 id=&quot;endianness--bitshifting&quot;&gt;Endianness &amp;amp; Bitshifting&lt;/h2&gt;
&lt;p&gt;On a little-endian system, &lt;code class=&quot;highlighter-rouge&quot;&gt;int 256&lt;/code&gt; is stored across 4 bytes &lt;strong&gt;in memory&lt;/strong&gt; like this:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Multiplier&lt;/th&gt;
      &lt;th&gt;256⁰&lt;/th&gt;
      &lt;th&gt;256¹&lt;/th&gt;
      &lt;th&gt;256²&lt;/th&gt;
      &lt;th&gt;256³&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Value&lt;/td&gt;
      &lt;td&gt;00&lt;/td&gt;
      &lt;td&gt;01&lt;/td&gt;
      &lt;td&gt;00&lt;/td&gt;
      &lt;td&gt;00&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Address&lt;/td&gt;
      &lt;td&gt;1000&lt;/td&gt;
      &lt;td&gt;1001&lt;/td&gt;
      &lt;td&gt;1002&lt;/td&gt;
      &lt;td&gt;1003&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;You might imagine that iteratively bitshifting this value and masking against &lt;code class=&quot;highlighter-rouge&quot;&gt;0xff&lt;/code&gt; would provide the constituent bytes in the little-endian order, but this is not the case.&lt;/p&gt;

&lt;p&gt;Bit shifting is always applied against a big-endian representation. This is because when the integer is loaded into the CPU’s register, it is effectively represented in big-endian format.&lt;/p&gt;

&lt;p&gt;The CPU register is not byte-addressable, so in this context endianness does not make sense.&lt;/p&gt;

&lt;p&gt;This means that bitwise operations are applied to a big-endian representation of the number.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// When the integer is loaded into the CPU's register, it is the 
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// equivalent of conversion to big-endian format - the number in
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the CPU register is big-endian.
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;//
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// This means that bitwise operations are applied to a big-endian
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// representation of the number:
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// 00 00 01 00
&lt;/span&gt;	
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;num: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// 256
&lt;/span&gt;	
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(num &amp;gt;&amp;gt; 0) &amp;amp; 0xff = &quot;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// 0
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(num &amp;gt;&amp;gt; 8) &amp;amp; 0xff = &quot;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// 1
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(num &amp;gt;&amp;gt; 16) &amp;amp; 0xff = &quot;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// 0
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(num &amp;gt;&amp;gt; 24) &amp;amp; 0xff = &quot;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// 0
&lt;/span&gt;	
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In short, you probably don’t need to worry about endianness when bit shifting - but bear in mind even if your system is little-endian, the bitshift operation takes place on a big endian representation.&lt;/p&gt;

&lt;h2 id=&quot;the-register&quot;&gt;The Register&lt;/h2&gt;
&lt;p&gt;A 32-bit CPU register holding a 32-bit value is neither big-endian nor little-endian - it is a register holding a 32-bit value &lt;a href=&quot;https://developer.ibm.com/articles/au-endianc/&quot;&gt;see ref&lt;/a&gt;. It is &lt;em&gt;kind of&lt;/em&gt; big-endian though, since the rightmost bit is the least significant bit and the leftmost bit is the most significant.&lt;/p&gt;

&lt;h2 id=&quot;system-endianness-linux&quot;&gt;System Endianness: Linux&lt;/h2&gt;
&lt;p&gt;To find endianness on a modern Linux kernel:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lscpu | grep Endian

&lt;span class=&quot;c&quot;&gt;# result:&lt;/span&gt;
Byte Order:            Little Endian
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;conversion-to-an-array-of-bytes&quot;&gt;Conversion to an Array of Bytes&lt;/h2&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;iomanip&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BITS 8
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BYTES_PER_INT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;intToCharArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BYTES_PER_INT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BYTES_PER_INT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Enter an integer: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not an integer. Exiting...&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BYTES_PER_INT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;intToCharArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;'0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static_cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.ibm.com/articles/au-endianc/&quot;&gt;Writing endian-independent code in C&lt;/a&gt;, IBM Developer article&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 15 Aug 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/08/Convert-integer-to-array-of-char-bytes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/08/Convert-integer-to-array-of-char-bytes/</guid>
      </item>
      
    
      
      <item>
        <title>Information Entropy</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Entropy_(information_theory)&quot;&gt;Information Entropy&lt;/a&gt; is the average rate at which information is produced by a stochastic(random) source of data.&lt;/p&gt;

&lt;h2 id=&quot;what-is-information&quot;&gt;What is Information?&lt;/h2&gt;
&lt;p&gt;Information is what you get when uncertainty around an event is decreased. Before a fair coin-toss, there is an equal probabilty of the toss resulting in heads or tails - the result is uncertain. After the toss, there is no more uncertainty and information (the result of the toss) has been gained.&lt;/p&gt;

&lt;p&gt;The amount of information in a message is defined as the minimum number of bits required to represent all possible meanings of the message, assuming that all messages are equally likely (&lt;a href=&quot;https://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/1119096723/ref=sr_1_1?keywords=applied+cryptography&amp;amp;qid=1562511120&amp;amp;s=books&amp;amp;sr=1-1&quot;&gt;Scshneier, 1996&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In terms of the coin toss, because there are only two outcomes you can represent all possible outcomes with a single bit.&lt;/p&gt;

&lt;p&gt;Entropy is used to quantify uncertainty. For a coin toss, entropy is 1 since this represents the minimum number of bits to represent all possible outcomes.&lt;/p&gt;

&lt;h2 id=&quot;definition-of-entropy&quot;&gt;Definition of Entropy&lt;/h2&gt;
&lt;p&gt;Entropy is a way of measuring the uncertainty of a stochastic variable (&lt;a href=&quot;https://blogs.cisco.com/security/on_information_entropy&quot;&gt;Schiffman&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The amount of information that could be conveyed by a message is measured by the &lt;strong&gt;entropy&lt;/strong&gt; of the message.&lt;/p&gt;

&lt;p&gt;The amount of information in a message is the minimum number of bits required to represent the message.&lt;/p&gt;

&lt;p&gt;The entropy of a message indicating whether to proceed or not can be represented by a single bit, since by definition a bit has one of two states:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Proceed?&lt;/th&gt;
      &lt;th&gt;Minimum Representation in bits&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;No&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The days of the week can be represented by slightly less than 3 bits:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Day of week&lt;/th&gt;
      &lt;th&gt;Minimum representation in bits&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Sunday&lt;/td&gt;
      &lt;td&gt;000&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Monday&lt;/td&gt;
      &lt;td&gt;001&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Tuesday&lt;/td&gt;
      &lt;td&gt;010&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Wednesday&lt;/td&gt;
      &lt;td&gt;011&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Thursday&lt;/td&gt;
      &lt;td&gt;100&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Friday&lt;/td&gt;
      &lt;td&gt;101&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Saturday&lt;/td&gt;
      &lt;td&gt;110&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Unused&lt;/td&gt;
      &lt;td&gt;111&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There are 7 potential days of the week, so the information must be represented by a minimum of 7 binary states.
How many bits are required to represent 7 distinct states?&lt;/p&gt;

&lt;p&gt;The lowest number that can represent 7 states is 6: &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;0,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;5,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt; - as shown above in binary format. The number 6 represented in binary format is 110, or 2&lt;sup&gt;2.59&lt;/sup&gt;, or log&lt;sub&gt;2&lt;/sub&gt; 6.&lt;/p&gt;

&lt;p&gt;Because a binary system represents data in discrete bits, the number of bits required to represent a number must be an integer not a fraction. In this case, 3 bits are required to represent the 7 states.&lt;/p&gt;

&lt;p&gt;In a base 2 system, this generalises to 2&lt;sup&gt;n&lt;/sup&gt; where n is the minimum number of digits required to represent all possible states.&lt;/p&gt;

&lt;p&gt;Entropy, though measured in bits, is &lt;strong&gt;not&lt;/strong&gt; information. It is rather a measurement of how much information is &lt;strong&gt;not available&lt;/strong&gt; when the outcome of a random source of information is unknown.&lt;/p&gt;

&lt;h2 id=&quot;mnimum-representation-in-bits&quot;&gt;Mnimum Representation in Bits&lt;/h2&gt;
&lt;p&gt;The minimum power of 2 that is greater than or equal to the number of states.&lt;/p&gt;

&lt;p&gt;Where the number of states is n,&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;log₂ n
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The binary logarithm (log&lt;sub&gt;2&lt;/sub&gt; n) is the power to which the number 2 must be raised to obtain the value n. For any real number x:&lt;/p&gt;

&lt;p&gt;x = log&lt;sub&gt;2&lt;/sub&gt;⁡ n ⟺ 2&lt;sup&gt;x&lt;/sup&gt; = n.&lt;/p&gt;

&lt;p&gt;Double a number adds 1 to binary logarithm:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;sup&gt;3&lt;/sup&gt; (8)&lt;/th&gt;
      &lt;th&gt;2&lt;sup&gt;2&lt;/sup&gt; (4)&lt;/th&gt;
      &lt;th&gt;2&lt;sup&gt;1&lt;/sup&gt; (2)&lt;/th&gt;
      &lt;th&gt;2&lt;sup&gt;0&lt;/sup&gt; (1)&lt;/th&gt;
      &lt;th&gt;Decimal&lt;/th&gt;
      &lt;th&gt;log&lt;sub&gt;2&lt;/sub&gt;⁡ n&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;upper-limits&quot;&gt;Upper Limits&lt;/h2&gt;
&lt;p&gt;For storage of raw data, not the information content of the data:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;2 bits: 4 different values&lt;/li&gt;
  &lt;li&gt;3 bits: 8 different values&lt;/li&gt;
  &lt;li&gt;4 bits: 16 different values&lt;/li&gt;
  &lt;li&gt;8 bits: 256 different values&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;practical-uses&quot;&gt;Practical Uses&lt;/h2&gt;
&lt;p&gt;When calculating the entropy of a password or passphrase, entropy is defined as log base 2 of the number of characters/words that the password has been randomly selected from to the power of the password/passphrase length.&lt;/p&gt;

&lt;p&gt;The Bash script below calculates the entropy of words that have been pseudo-randomly selected from a word list. In this case, character set is the number of words available to select from and the length is the number of pseudorandom words output.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#/bin/bash&lt;/span&gt;
...
&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;entropy &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WORDSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WORDS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
	python3 - &lt;span class=&quot;sh&quot;&gt;&amp;lt;&amp;lt;- EOF
	import math; import os;
	# Entropy is log base 2 of the keyspace to the power of the length 
	r = math.log(int(os.environ['WORDSET']) ** int(os.environ['WORDS']), 2)
	print(round(r, 2))
	EOF
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://math.stackexchange.com/a/768356/559161&quot;&gt;Good short description of entropy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://pages.cs.wisc.edu/~sriram/ShannonEntropy-Intuition.pdf&quot;&gt;Verbose description of entropy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.cisco.com/security/on_information_entropy&quot;&gt;On Information entropy&lt;/a&gt;, Cisco blog&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Entropy_(information_theory)&quot;&gt;Information Entropy&lt;/a&gt;, Wikipedia&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 12 Aug 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/08/Information-Entropy/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/08/Information-Entropy/</guid>
      </item>
      
    
      
      <item>
        <title>Explicit Conversion Constructor in C++</title>
        <description>&lt;p&gt;Prepending the keyword &lt;code class=&quot;highlighter-rouge&quot;&gt;explicit&lt;/code&gt; to a C++ constructor declaration (i.e. adding the &lt;code class=&quot;highlighter-rouge&quot;&gt;explicit&lt;/code&gt; function specifier to the constructor within the class declaration) prevents unwanted type conversions.&lt;/p&gt;

&lt;p&gt;Without the &lt;code class=&quot;highlighter-rouge&quot;&gt;explicit&lt;/code&gt; function specifier, a constructor is a &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/converting_constructor&quot;&gt;converting constructor&lt;/a&gt; - the type can be initialised by assigning a variable of the appropriate type. Prior to C++11, the constructor needed to be called with a single non-default parameter. For example:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;c1&quot;&gt;// Converting constructor
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&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;c1&quot;&gt;// Converting constructor
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;B&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&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;k&quot;&gt;explicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&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;c1&quot;&gt;// Converting constructors
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// -----------------------
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Copy initialisation
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// Copy list initialisation
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Direct initialisation
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Direct list initialisation
&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Explicit conversion constructors
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// --------------------------------
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// NOT ALLOWED: Error
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// NOT ALLOWED: Error
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Direct initalisation OK
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Direct list initialisation OK
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&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;c1&quot;&gt;// OK - exlicit cast does a static cast, direct initialisation
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that prior to C++11, converting constructors needed to have a single non-default parameter.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/explicit_keyword.htm&quot;&gt;Explicit conversion constructors&lt;/a&gt;: IBM Knowledge Centre&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/converting_constructor&quot;&gt;Converting constructors&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 11 Aug 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/08/Explicit-Conversion-Constructor-in-C++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/08/Explicit-Conversion-Constructor-in-C++/</guid>
      </item>
      
    
      
      <item>
        <title>Lambdas in C++</title>
        <description>&lt;p&gt;In C++ a &lt;em&gt;lambda expression&lt;/em&gt; or &lt;em&gt;lambda function&lt;/em&gt; is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Closure_(computer_programming)&quot;&gt;closure&lt;/a&gt;: an unnamed (anonymous) function that is passed inline - usually to another function. Lambda expressions are a concise way of creating simple function objects.&lt;/p&gt;

&lt;p&gt;If necessary, lambda expressions can capture variables from their context.&lt;/p&gt;

&lt;p&gt;Lambda expressions are useful for passing an operation as an argument into an algorithm.&lt;/p&gt;

&lt;p&gt;Using a lambda expression is like using a function pointer, but without the need to create a named object.&lt;/p&gt;

&lt;p&gt;In C++ a Lambda expression can only be considered a closure when there is something in the capture clause (&lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;syntax&quot;&gt;Syntax&lt;/h2&gt;
&lt;p&gt;Full syntax:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// [captures] (params) -&amp;gt; returnType { function body }
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Concrete example: capture a by reference; parameter is int; lambda expression returns an int 
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&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;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If the return type can be deduced from the return statement in the function body, the return type can be ommitted:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// [captures] (params) { function body }
// Concrete example: No captures, parameter is int, lambda expression returns an int
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If the lambda expression takes no arguments:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// [captures] { function body }
// Concrete example: no captures, no parameters:
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For other syntax options: &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/lambda&quot;&gt;https://en.cppreference.com/w/cpp/language/lambda&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;generic-lambda-expression&quot;&gt;Generic Lambda Expression&lt;/h2&gt;
&lt;p&gt;Lambda expressions can take arguments that have arbitrary types.&lt;/p&gt;

&lt;p&gt;If a parameter is marked &lt;code class=&quot;highlighter-rouge&quot;&gt;auto&lt;/code&gt;, the type can be deduced:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intsVec&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the lambda expression becomes an instance of type:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// unnamed
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&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;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

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

&lt;p&gt;If a generic lambda has no captures, the closure type has a “public non-virtual non-explicit const conversion function template to pointer to function” &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf#subsection.5.1.2&quot;&gt;see the standards document&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;passing-generic-lambda-to-template-function&quot;&gt;Passing Generic Lambda to Template Function&lt;/h2&gt;
&lt;p&gt;In the following example, &lt;code class=&quot;highlighter-rouge&quot;&gt;ForEach()&lt;/code&gt; can transform elements of a vector - the type of the element being generic.&lt;/p&gt;

&lt;p&gt;The generic lambda is straightforward enough, but note the template function signature - one way or the other, you should let the compiler deduce the type for the Lambda expression.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&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;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Equivalent to the above - less typing with `auto`!
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForEachAuto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lambdaExpression&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&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;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lambdaExpression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&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;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;c1&quot;&gt;// intVec is now { 0,1,4,9,16,25 }	
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doublesVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;ForEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doublesVec&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;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&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;c1&quot;&gt;// doublesVec is now { 1.21, 4.84, 10.89 }
&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that the definition of the generic function that accepts the lambda as a parameter can either use &lt;code class=&quot;highlighter-rouge&quot;&gt;template&lt;/code&gt; syntax or the &lt;code class=&quot;highlighter-rouge&quot;&gt;auto&lt;/code&gt; keyword.&lt;/p&gt;

&lt;h2 id=&quot;captures&quot;&gt;Captures&lt;/h2&gt;
&lt;p&gt;The captured variables can be passed by value or by reference.&lt;/p&gt;

&lt;h3 id=&quot;copy-values&quot;&gt;Copy Values&lt;/h3&gt;
&lt;p&gt;Implicitly capture all automatic variables by value - copy values into the lambda expression:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id=&quot;pass-by-reference&quot;&gt;Pass by Reference&lt;/h3&gt;

&lt;p&gt;Implicitly capture all automatic variables by reference - copy references into the lambda expression:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;override-the-default-capture-method&quot;&gt;Override the Default Capture Method&lt;/h3&gt;
&lt;p&gt;You can set a default capture method and override this for individual variables:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Capture by reference, except a which is captured by copy:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Capture all by copy, except a which is captured by reference:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;callbacks&quot;&gt;Callbacks&lt;/h2&gt;
&lt;p&gt;A callback is a function which is invoked by another function. The calling function has the option of calling different callbacks - perhaps as a function pointer.&lt;/p&gt;

&lt;p&gt;C++ allows a Lambda expression to be used as a callback - as exemplified above.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf#subsection.5.1.2&quot;&gt;C++ Standards Committee ISOCPP&lt;/a&gt;: Lambda expressions&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Closure_(computer_programming)&quot;&gt;Closures&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/lambda&quot;&gt;Syntax&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/17233649/3590673&quot;&gt;Generic Lambdas&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UOu_1Foq4mk&quot;&gt;CopperSpice Video: Lambdas in Action&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Fri, 09 Aug 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/08/Lambdas-in-C++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/08/Lambdas-in-C++/</guid>
      </item>
      
    
      
      <item>
        <title>Build an Array of Strings From a File in C</title>
        <description>&lt;p&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; to read lines from a file, and add them to dynamically allocated memory:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Please supply a file path:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s &amp;lt;file path&amp;gt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&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;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&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;n&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ERROR&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&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;c1&quot;&gt;// Read lines from file, allocate memory and build an array of lines
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nLines&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineLength&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sizeIncrement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sizeIncrement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineLength&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Memory reallocation is expensive - don't reallocate on every iteration.
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sizeIncrement&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;n&quot;&gt;sizeIncrement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sizeIncrement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

			&lt;span class=&quot;c1&quot;&gt;// Don't just overwrite with realloc - the original
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// pointer may be lost if realloc fails.
&lt;/span&gt;			&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;realloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sizeIncrement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmp&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;n&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;realloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&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;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmp&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;c1&quot;&gt;// Remove \n from the line.
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strcspn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Allocate space on the heap for the line.
&lt;/span&gt;		&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineLength&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Copy the getline buffer into the new string.
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Keep track of the number of lines read for later use.
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;nLines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;c1&quot;&gt;// Do something with the array of strings.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nLines: %lu&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%lu&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; %s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&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;c1&quot;&gt;// Free the buffer utilised by `getline()`.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineBuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Free the array of strings.
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;fclose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;sizet-vs-ssizet&quot;&gt;size_t vs ssize_t&lt;/h2&gt;
&lt;p&gt;Note that the return value of &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; is assigned to &lt;code class=&quot;highlighter-rouge&quot;&gt;ssize_t lineLength&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The reason that the &lt;code class=&quot;highlighter-rouge&quot;&gt;ssize_t&lt;/code&gt; type is used is that &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; can return a negative value (actually -1) in the event of failure or the end-of-file condition.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ssize_t&lt;/code&gt; is guaranteed to be able to store values in the range -1 to &lt;code class=&quot;highlighter-rouge&quot;&gt;SSIZE_MAX&lt;/code&gt; and should be used for a count of bytes or an error indication.&lt;/p&gt;

&lt;h2 id=&quot;realloc&quot;&gt;Realloc&lt;/h2&gt;
&lt;p&gt;Note that you should check that &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; succeeds by checking for a non-null return value - or responding to the null case as in the example above.&lt;/p&gt;

&lt;p&gt;You can do this by assigning realloc to a temporary variable, only copying it across to your target variable when you are sure that &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; succeeded.&lt;/p&gt;

&lt;p&gt;Otherwise, you risk writing &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt; to your target variable, thereby causing a memory leak (since you can’t access the pointer to free memory).&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/23680335/3590673&quot;&gt;Good article on debugging memory allocation issues&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/google/sanitizers&quot;&gt;Address sanitizer tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 29 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Build-an-Array-of-Strings-From-a-File-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Build-an-Array-of-Strings-From-a-File-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Convert an Array of Unsigned Chars to an int32_t Value</title>
        <description>&lt;p&gt;In C or C++, an array of four &lt;code class=&quot;highlighter-rouge&quot;&gt;unsigned char&lt;/code&gt; values (four raw bytes) can be converted to a single &lt;code class=&quot;highlighter-rouge&quot;&gt;int32_t&lt;/code&gt; value using bitwise operations.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;inttypes.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;c1&quot;&gt;// An array of raw bytes
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xbe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;c1&quot;&gt;// To pack into a 4 byte data type, shift each element the 
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// appropriate number of bits and perform bitwise OR on
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// all shifted elements.
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;raw&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;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&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;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%%u result = %u&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 3735928559
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;/h2&gt;
&lt;p&gt;An array of unsigned char containing the decimal values 222, 173, 190, 239 can represented in binary format:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Decimal&lt;/th&gt;
      &lt;th&gt;Binary&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;222&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;11011110&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;173&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;10101101&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;190&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;10111110&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;239&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;11101111&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;To get these values packed into a 4 byte data type such as &lt;code class=&quot;highlighter-rouge&quot;&gt;uint32_t&lt;/code&gt;, the first (single byte) value in the array should be inserted into the most significant byte. The second should be inserted into the next most significant byte, and so on.&lt;/p&gt;

&lt;p&gt;This can be achieved by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Bit shifting each byte to it’s required position&lt;/li&gt;
  &lt;li&gt;Performing a bitwise OR operation on all bytes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using the values from the above example:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 11011110 &amp;lt;&amp;lt; 24
+-----------------+-----------------+-----------------+-----------------+
| 1 1 0 1 1 1 1 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
+-----------------+-----------------+-----------------+-----------------+

# 10101101 &amp;lt;&amp;lt; 16
+-----------------+-----------------+-----------------+-----------------+
| 0 0 0 0 0 0 0 0 | 1 0 1 0 1 1 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
+-----------------+-----------------+-----------------+-----------------+

# 10111110 &amp;lt;&amp;lt; 8
+-----------------+-----------------+-----------------+-----------------+
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 0 1 1 1 1 1 0 | 0 0 0 0 0 0 0 0 |
+-----------------+-----------------+-----------------+-----------------+

# The least significant byte doesn't need shifting
+-----------------+-----------------+-----------------+-----------------+
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 1 1 1 0 1 1 1 1 |
+-----------------+-----------------+-----------------+-----------------+

Perform bitwise OR on all the above values:
+-----------------+-----------------+-----------------+-----------------+
| 1 1 0 1 1 1 1 0 | 1 0 1 0 1 1 0 1 | 1 0 1 1 1 1 1 0 | 1 1 1 0 1 1 1 1 |
+-----------------+-----------------+-----------------+-----------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gnu.org/software/libc/manual/html_node/Integers.html&quot;&gt;Integers in C&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Tue, 23 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Convert-an-Array-of-Unsigned-Chars-to-an-int32_t-Value/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Convert-an-Array-of-Unsigned-Chars-to-an-int32_t-Value/</guid>
      </item>
      
    
      
      <item>
        <title>Find Custom Data Types in a C++ Project</title>
        <description>&lt;p&gt;If your looking through an existing C++ project, it is likely that you will come across custom data types.&lt;/p&gt;

&lt;p&gt;For example, if you see the following:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pair&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Blob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strUnHex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strSrc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;…you just know that &lt;code class=&quot;highlighter-rouge&quot;&gt;Blob&lt;/code&gt; is an object of some sort. The first_type in the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::pair&lt;/code&gt; could be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A class-defined object&lt;/li&gt;
  &lt;li&gt;A struct defined object&lt;/li&gt;
  &lt;li&gt;A type alias&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;searching-a-project&quot;&gt;Searching a Project&lt;/h2&gt;
&lt;p&gt;Use grep:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;myProject

grep -nr &lt;span class=&quot;s2&quot;&gt;&quot;search term&quot;&lt;/span&gt; .
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;search-project-for-custom-type&quot;&gt;Search Project for Custom Type&lt;/h2&gt;
&lt;p&gt;If you want to determine information about a custom data type, finding where it is defined/aliased is a good idea:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;grep &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the specified options &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the current directory:
grep -nr &lt;span class=&quot;s2&quot;&gt;&quot;using Blob&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;class Blob&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;struct Blob&quot;&lt;/span&gt; .

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
./src/path/Blob.h:30:using Blob &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; std::vector &amp;lt;unsigned char&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;At this point, you don’t even need to open &lt;code class=&quot;highlighter-rouge&quot;&gt;Blob.h&lt;/code&gt; to know that &lt;code class=&quot;highlighter-rouge&quot;&gt;Blob&lt;/code&gt; is an alias for &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&amp;lt;unsigned char&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You could also try grepping for &lt;code class=&quot;highlighter-rouge&quot;&gt;typedef&lt;/code&gt; statements:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# grep for the term &quot;typedef&amp;lt;any number of any characters&amp;gt;Blob&quot; recursively starting in the current directory: &lt;/span&gt;
grep -nr &lt;span class=&quot;s2&quot;&gt;&quot;typedef.*Blob&quot;&lt;/span&gt; .
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/doc/tutorial/other_data_types/&quot;&gt;Data types in C++&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 22 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Find-Custom-Data-Types-in-a-C++-Project/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Find-Custom-Data-Types-in-a-C++-Project/</guid>
      </item>
      
    
      
      <item>
        <title>Arrays and Slices in Rust</title>
        <description>&lt;p&gt;Basic cheatsheet for Rust arrays and slices.&lt;/p&gt;

&lt;p&gt;A rust array is a stack-allocated list of objects of a set type and fixed length.&lt;/p&gt;

&lt;p&gt;Initialise:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// Arrays in rust are fixed length.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// Specify type and length in square brackets to initialize.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&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;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The correct data type and array length are now fixed and expected.&lt;/p&gt;

&lt;p&gt;To print an array use Debug print:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;dereferencing&quot;&gt;Dereferencing&lt;/h2&gt;
&lt;p&gt;Dereference elements in the “universal” way:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.len&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;arr[{}] is {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;mutable-arrays&quot;&gt;Mutable Arrays&lt;/h2&gt;
&lt;p&gt;Arrays elements can be mutable, but the array length and data type is fixed:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr_to_change&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;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;arr_to_change&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;iteration&quot;&gt;Iteration&lt;/h2&gt;
&lt;p&gt;Arrays are not iterable. To iterate over each element, convert an array to iterator by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;.iter()&lt;/code&gt;, a slice method:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Otherwise you could make a slice from the array:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.first&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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;first! &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sliced: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Enumerate the loop iterator to track an index:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr_to_change&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.enumerate&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;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;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)};&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;print!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&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;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you try to access array elements that are out-of-bounds, Rust will “panic” - the programme terminates immediately. This prevents buffer overread bugs.&lt;/p&gt;

&lt;h2 id=&quot;memory-allocation&quot;&gt;Memory Allocation&lt;/h2&gt;
&lt;p&gt;Get memory allocated:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Array arr is {} bytes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size_of_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;slices&quot;&gt;Slices&lt;/h2&gt;
&lt;p&gt;Slices are a view into a block of memory represented by a pointer and a length.
In other words, a slice is a view into an array.&lt;/p&gt;

&lt;p&gt;Make a slice from the full array:&lt;/p&gt;
&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sl is {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Make a slice of elements 0 and 1 - [0..2] is exclusive of the upper bound:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&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;err&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// or overtly set the type:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&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;err&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sl2 is {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;access-slice-elements&quot;&gt;Access Slice Elements&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;get()&lt;/code&gt; method returns an element of a slice at the given index as an &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt;. In the example above, &lt;code class=&quot;highlighter-rouge&quot;&gt;sl2.get(2)&lt;/code&gt; returns &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; because there is no element at that index - this prevents failure if the index is out of bounds.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;get()&lt;/code&gt; uses &lt;code class=&quot;highlighter-rouge&quot;&gt;Option&lt;/code&gt; to give type-safe bound checking array access.&lt;/p&gt;

&lt;p&gt;Note that if you &lt;code class=&quot;highlighter-rouge&quot;&gt;unwrap()&lt;/code&gt; an Option type that has a &lt;code class=&quot;highlighter-rouge&quot;&gt;None&lt;/code&gt; value, the programme panics.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sl2.get({}) returns {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// `val.unwrap()` at this point causes a panic.&lt;/span&gt;
  &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Nothing at index {}. Move along.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;c&quot;&gt;// Return an option&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sl2.get(1) returns {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get&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;c&quot;&gt;// Unwrap the returned value&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sl2.get(1) returns {:?}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sl2&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get&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;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://riptutorial.com/Download/rust.pdf&quot;&gt;Rust riptutorial book (PDF)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/std/primitive.slice.html&quot;&gt;Rust docs primitive type slice&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/std/primitive.array.html&quot;&gt;Rust docs primitive type array&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 20 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/arrays-slices-in-rust/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/arrays-slices-in-rust/</guid>
      </item>
      
    
      
      <item>
        <title>Passing Strings in C</title>
        <description>&lt;p&gt;If you need to operate on strings, it’s helpful to abstract this away into separate functions (which can be held in different files) to keep your code clean and to reduce repetition.&lt;/p&gt;

&lt;h2 id=&quot;amend-stack-allocated-string-in-a-function&quot;&gt;Amend Stack-Allocated String in a Function&lt;/h2&gt;
&lt;p&gt;In C, if you need to amend a string in a called function, pass a pointer to the first char in the string as an argument to the function.&lt;/p&gt;

&lt;p&gt;It is also common to pass in the length of the string:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lengthMyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you don’t pass the length, you can get this value from within your function by counting up to a &lt;code class=&quot;highlighter-rouge&quot;&gt;NUL&lt;/code&gt; char - which you can do easily with &lt;code class=&quot;highlighter-rouge&quot;&gt;strlen()&lt;/code&gt; from the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;string.h&amp;gt;&lt;/code&gt; header:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myString&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;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// Access each char in the string
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myString[%lu] = %c&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here’s another approach using a while loop to check for the end of the string:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;// Within this function, `line` is initially a pointer to the first
// char in a string (Null terminated char array).
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&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;c1&quot;&gt;// Continue if the value pointed at by `line` is not NUL
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&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;c1&quot;&gt;// Dereference `line` and assign a new value '0'
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// then advance the pointer
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'0'&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;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;gdgegryt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;If you have allocated storage for the string outside the function, which you cannot exceed within the function, it’s probably a good idea to pass in the size.&lt;/p&gt;

&lt;h2 id=&quot;function-does-not-alter-the-string&quot;&gt;Function Does Not Alter the String&lt;/h2&gt;
&lt;p&gt;If you’re not modifying the string, you can pass a &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; pointer and omit the length:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;printString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;amend-a-passed-in-buffer-with-memory-allocation&quot;&gt;Amend a Passed-in Buffer With Memory Allocation&lt;/h2&gt;
&lt;p&gt;If the function needs to modify a dynamically allocated (i.e. heap-allocated) string buffer from the caller, you must pass in a pointer to a pointer.&lt;/p&gt;

&lt;p&gt;In C, function arguments are passed by value. This means that to modify a variable from within a function, you need a &lt;strong&gt;pointer&lt;/strong&gt; to the variable.&lt;/p&gt;

&lt;p&gt;This allows you to derefence the pointer, and potentially amend the value in the memory address being pointed to.&lt;/p&gt;

&lt;p&gt;When you dynamically allocate memory to store a string (using one of the &lt;code class=&quot;highlighter-rouge&quot;&gt;malloc()&lt;/code&gt; family of functions) you are assigning an area of heap memory to a &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you need to change what is pointed to from with the function (e.g you might need to &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; memory) the function must receive a pointer to the &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt;. In this way, you can dereference the &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt; to change the value held in &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; - which in this case is the memory address of the dynamically allocated storage.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;char **s          char *s        char
+---+             +---+          +---+---+---+---+
| &amp;amp;-|------------&amp;gt;| &amp;amp;-|---------&amp;gt;|'a'|'b'|'c'| 0 |
+---+             +---+          +---+---+---+---+
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * Within function, amending *s changes the memory
 * address of the dynamically allocated string.
 **/&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_xy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&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;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;realloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Add a null terminator
&lt;/span&gt;	&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// The size of s is unknown at compile time.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Remove newline - maybe realloc memory after this.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strcspn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;add_xy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// getline() allocated memory, add_xy() reallocated. Free it.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


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

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/1863138/3590673&quot;&gt;SO Answer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/passing-strings-in-C&quot;&gt;GitHub repo with code from this article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 20 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Passing-Strings-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Passing-Strings-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Get a line from stdin in C</title>
        <description>&lt;p&gt;If you want to get a single line of &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt; in C, &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; is the go-to function.&lt;/p&gt;

&lt;p&gt;To get a single line from &lt;code class=&quot;highlighter-rouge&quot;&gt;stdin&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Please enter a line:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineSize&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;lineSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;You entered %s, which has %zu chars.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineSize&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Why do we have to &lt;code class=&quot;highlighter-rouge&quot;&gt;free(line)&lt;/code&gt;? After all, there are no &lt;code class=&quot;highlighter-rouge&quot;&gt;malloc&lt;/code&gt; family functions in the above code?&lt;/p&gt;

&lt;p&gt;The answer is that &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; allocates memory to the buffer (in the example above, &lt;code class=&quot;highlighter-rouge&quot;&gt;line&lt;/code&gt;) as required.&lt;/p&gt;

&lt;h2 id=&quot;how-does-getline-work&quot;&gt;How Does getline() Work?&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; receives a pointer to a buffer in which to store the line string, a pointer to the size of the buffer, and a pointer to the input stream.&lt;/p&gt;

&lt;p&gt;The function does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Allocates memory for the string buffer on the heap&lt;/li&gt;
  &lt;li&gt;Updates the len variable to track the memory allocation&lt;/li&gt;
  &lt;li&gt;Reads a line into the heap-allocated string buffer&lt;/li&gt;
  &lt;li&gt;Returns the length of the string that has been read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the newline character, not the null terminator, is counted in the length.&lt;/p&gt;

&lt;p&gt;The memory allocated may be more than required for the input characters. If not enough memory is allocated initially, &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; can &lt;code class=&quot;highlighter-rouge&quot;&gt;realloc()&lt;/code&gt; a longer buffer, while updating the &lt;code class=&quot;highlighter-rouge&quot;&gt;line&lt;/code&gt; varible to point to the new buffer and updating &lt;code class=&quot;highlighter-rouge&quot;&gt;len&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;getline()&lt;/code&gt; is called again, the original buffer is re-used unless reallocation of memory is required.&lt;/p&gt;

&lt;h2 id=&quot;example-from-man-getline&quot;&gt;Example from &lt;code class=&quot;highlighter-rouge&quot;&gt;man getline&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The example in the man page loops through a file, collecting all lines into a single string. We can adapt this to read a file passed in as a command line argument:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;please specify a file.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&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;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Retrieved line of length %zu :&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&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;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fclose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.coursera.org/lecture/interacting-system-managing-memory/reading-a-file-with-getline-Wk8aB&quot;&gt;Courseera video, Duke Uni&lt;/a&gt;: Reading a file with getline().&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Fri, 19 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Get-a-line-from-stdin-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Get-a-line-from-stdin-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Display char as Hexadecimal String in C++</title>
        <description>&lt;p&gt;Displaying a char or a collection of chars as a hexadecimal string in C++ is surprisingly tricky.&lt;/p&gt;

&lt;p&gt;For context, let’s say you are collecting bytes from &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/urandom&lt;/code&gt; in a &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&lt;/code&gt; and you need to display them to the user:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;fstream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;fstream&amp;gt;
#include &amp;lt;iterator&amp;gt;
#include &amp;lt;iomanip&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Enter the number of random bytes to fetch from /dev/urandom:&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not an integer. Exiting...&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ifstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/dev/urandom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ios&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ios&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cerr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Couldn't open /dev/urandom. Exiting...&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randomBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randomBytes&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;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Displaying bytes: method 1
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// --------------------------
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randomBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;'0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Displaying bytes: method 2
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// --------------------------
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randomBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%02hhx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;method-one-stdcout&quot;&gt;Method One: std::cout&lt;/h2&gt;
&lt;p&gt;Method 1 as shown above is probably the more C++ way:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cast to an unsigned int&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;std::hex&lt;/code&gt; to represent the value as hexadecimal digits&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;std::setw&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;std::setfill&lt;/code&gt; from &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;iomanip&amp;gt;&lt;/code&gt; to format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that you need to mask the cast int against &lt;code class=&quot;highlighter-rouge&quot;&gt;0xff&lt;/code&gt; to display the least significant byte: &lt;code class=&quot;highlighter-rouge&quot;&gt;(0xff &amp;amp; (unsigned int)el)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Otherwise, if the highest bit is set the cast will result in the three most significant bytes being set to &lt;code class=&quot;highlighter-rouge&quot;&gt;ff&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;method-2-printf&quot;&gt;Method 2: printf()&lt;/h2&gt;
&lt;p&gt;Method 2 uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt; function with the &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;%02hhx&quot;&lt;/code&gt; format string.&lt;/p&gt;

&lt;p&gt;This is pretty much C style code. It’s quite a bit shorter though!&lt;/p&gt;

</description>
        <pubDate>Fri, 12 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Display-char-as-Hexadecimal-String-in-C++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Display-char-as-Hexadecimal-String-in-C++/</guid>
      </item>
      
    
      
      <item>
        <title>User Input cin in C++</title>
        <description>&lt;p&gt;If an input variable is declared, and the value collected by &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; does not match, &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; returns false.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Entering an integer at this point works.
// Entering a value which is not an integer and not numeric, std::cin returns false.
// Entering a real number (with a decimal point): fractional part is discarded and integer is saved.
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It’s better to take input within a loop, with some input validation:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;typeinfo&amp;gt;
#include &amp;lt;limits&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&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;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Enter an int:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	
		&lt;span class=&quot;c1&quot;&gt;// Enter this block if taking input from cin has failed.
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&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;c1&quot;&gt;// The error flag is set on std::cin - future attempts to
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// get input will fail unless the error is cleared.
&lt;/span&gt;			&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

			&lt;span class=&quot;c1&quot;&gt;// The failed input is in the input buffer. The default for `ignore` is
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// to skip a single character. To be sure, remove the max streamsize
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// number of chars up until a newline is encountered
&lt;/span&gt;			&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numeric_limits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;streamsize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;continue&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;k&quot;&gt;break&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;You entered: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; returns false if the input can’t match the expected type (in this case, int).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin.ignore()&lt;/code&gt; extracts and discards unwanted values.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin.clear()&lt;/code&gt; changes the internal state of the stream - unsets the error flag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a working example, see &lt;a href=&quot;https://github.com/DavidCWebs/c-plus-plus-notes/blob/master/examples/input.cpp&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/53013577/3590673&quot;&gt;Entertaining SO Answer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 11 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/User-Input-cin-in-C++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/User-Input-cin-in-C++/</guid>
      </item>
      
    
      
      <item>
        <title>Guard One Liner in Bash</title>
        <description>&lt;p&gt;Add a one-line guard statement in Bash:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;-eq 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please supply a target file: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;lt;path/to/file&amp;gt;&quot;&lt;/span&gt;; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that multiple commands in the curly braces must each be terminated with a semi-colon.&lt;/p&gt;

&lt;p&gt;Note that there must be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A single space character between each curly brace and the contents.&lt;/li&gt;
  &lt;li&gt;A single space between the &lt;code class=&quot;highlighter-rouge&quot;&gt;[[&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;]]&lt;/code&gt; characters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Bash special variable &lt;code class=&quot;highlighter-rouge&quot;&gt;$#&lt;/code&gt; refers to the number of command line arguments. &lt;code class=&quot;highlighter-rouge&quot;&gt;$(basename $0)&lt;/code&gt; refers to the current script name.&lt;/p&gt;
</description>
        <pubDate>Fri, 05 Jul 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/07/Guard-One-Liner-in-Bash/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/07/Guard-One-Liner-in-Bash/</guid>
      </item>
      
    
      
      <item>
        <title>qsort Comparison Function</title>
        <description>&lt;p&gt;In C, the &lt;code class=&quot;highlighter-rouge&quot;&gt;qsort()&lt;/code&gt; function sorts an array in place using the &lt;a href=&quot;https://en.wikipedia.org/wiki/Qsort&quot;&gt;quickersort&lt;/a&gt; algorithm - a variation of &lt;a href=&quot;https://en.wikipedia.org/wiki/Quicksort&quot;&gt;quick sort&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;function-signature&quot;&gt;Function Signature&lt;/h2&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nmemb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Function arguments for &lt;code class=&quot;highlighter-rouge&quot;&gt;qsort()&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;base&lt;/code&gt;: pointer to the start of the array&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nmemb&lt;/code&gt;: Number of members in the array&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;size&lt;/code&gt;: Size of an individual element in the array&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;compar&lt;/code&gt;: Pointer to a comparison function that accepts 2 x &lt;code class=&quot;highlighter-rouge&quot;&gt;const void *&lt;/code&gt; arguments&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To use &lt;code class=&quot;highlighter-rouge&quot;&gt;qsort()&lt;/code&gt;, you need to include the stdlib.h header - i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;comparison-function&quot;&gt;Comparison Function&lt;/h2&gt;
&lt;p&gt;The comparison function must return an integer that is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Less than zero if the first argument is considered to be less than the second&lt;/li&gt;
  &lt;li&gt;Zero if the arguments are equal&lt;/li&gt;
  &lt;li&gt;Greater than zero if the first argument is considered to be greater than the second&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be careful with return values - especially if the values being compared are not integers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt; or ‘&amp;lt;’ rather than subtraction which may provide unexpected results if comparing non integer values.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note that the comparison function receives &lt;code class=&quot;highlighter-rouge&quot;&gt;const void *&lt;/code&gt; as arguments - and you may need to cast these within the comparison function.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;triangle&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&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;n&quot;&gt;Triangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compareTriangles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Triangle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&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;cm&quot;&gt;/**
* Sort an array of Triangles
*/&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sort_by_area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Triangle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&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;n&quot;&gt;qsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Triangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compareTriangles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;	
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The above example sorts an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;Triangle&lt;/code&gt; type defined objects according to area (&lt;code class=&quot;highlighter-rouge&quot;&gt;area()&lt;/code&gt; has been omitted for brevity).&lt;/p&gt;

&lt;p&gt;Note the nested conditional in &lt;code class=&quot;highlighter-rouge&quot;&gt;compareTriangles()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;If area of a and b &lt;strong&gt;are not&lt;/strong&gt; equal, return 1 if the area of a is greater than the area of b, -1 if not.&lt;/li&gt;
  &lt;li&gt;If the area of a and b &lt;strong&gt;are&lt;/strong&gt; equal, return 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also note the line &lt;code class=&quot;highlighter-rouge&quot;&gt;const Triangle *a = x, *b = y;&lt;/code&gt; which copies the input pointers into the object required for the comparison.&lt;/p&gt;

&lt;h2 id=&quot;pointer-conversion-in-comparator-function&quot;&gt;Pointer Conversion in Comparator Function&lt;/h2&gt;
&lt;p&gt;The comparator function receives &lt;code class=&quot;highlighter-rouge&quot;&gt;const void *&lt;/code&gt; type pointers - these should be cast in the comparator to the original type of the data passed in.&lt;/p&gt;

&lt;h2 id=&quot;multiple-indirection-double-pointers&quot;&gt;Multiple Indirection: Double Pointers&lt;/h2&gt;
&lt;p&gt;If the comparator function for qsort compares values in an array of pointers (pointer-to-pointer), cast to this within the comparator.&lt;/p&gt;

&lt;p&gt;For example, if the array to be sorted is an array of pointers, the comparator should cast the input void pointers to pointer to the underlying type pointer.&lt;/p&gt;

&lt;p&gt;The code below shows how an array of pointers to custom &lt;code class=&quot;highlighter-rouge&quot;&gt;card_t&lt;/code&gt; types is sorted:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/**
* Comparator function to sort an array of type card_t *
* card_t is a typedef defined struct, with value and suit (numeric) fields.
*
*/&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;card_ptr_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;card_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;card_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;card_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;card_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	
	&lt;span class=&quot;c1&quot;&gt;// Alternative way of handling the cast:
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// const card_t * const *c1 = inPtr1;
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// const card_t * const *c2 = inPtr2;
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// unsigned v1 = (*c1)-&amp;gt;value;
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// unsigned v2 = (*c2)-&amp;gt;value;
&lt;/span&gt;	
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&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;n&quot;&gt;card_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;card_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// ... add cards
&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;qsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&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;n&quot;&gt;card_ptr_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// ... free dynbamically allocated resources
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;More complete example:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&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;n&quot;&gt;person_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Compare by id
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;comparePeople&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr2&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;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inPtr2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Chris&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;person_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;qsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&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;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&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;n&quot;&gt;comparePeople&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&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;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;id: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;name: %s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</description>
        <pubDate>Fri, 14 Jun 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/06/qsort-Comparison-Function/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/06/qsort-Comparison-Function/</guid>
      </item>
      
    
      
      <item>
        <title>Integer Input in C</title>
        <description>&lt;p&gt;Objective: get an integer input from stdin.&lt;/p&gt;

&lt;p&gt;At first glance, &lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; looks like a reasonable way to collect integer input. The function allows formatted input to be collected (it’s name comes from the words “scan formatted”).&lt;/p&gt;

&lt;p&gt;To scan integer input, first declare an integer and pass a pointer to this to scanf:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scanf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;However, because stdin is inherently unconstrained (users can type anything), &lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; &lt;a href=&quot;https://stackoverflow.com/a/3302594/3590673&quot;&gt;may not be the best choice&lt;/a&gt;. You need to handle whitespace characters appropriately as well as clearing the input stream for subsequent input because &lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; doesn’t read newlines.&lt;/p&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;fscanf()&lt;/code&gt; which scans a &lt;code class=&quot;highlighter-rouge&quot;&gt;FILE&lt;/code&gt; stream and &lt;code class=&quot;highlighter-rouge&quot;&gt;sscanf()&lt;/code&gt; which scans a string are rational and useful choices because they operate on structured data.&lt;/p&gt;

&lt;h2 id=&quot;fgets-read-the-entire-line&quot;&gt;fgets: Read the Entire Line&lt;/h2&gt;
&lt;p&gt;It may be better to read the whole line using &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt;, and then process the input as required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt; to read an entire line of stdin within a while loop.&lt;/li&gt;
  &lt;li&gt;Check the length of the input buffer - even though &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt; discards extra input, the user should be informed if input has exceeded available space and allowed to re-enter the data.&lt;/li&gt;
  &lt;li&gt;Convert input to an integer using &lt;code class=&quot;highlighter-rouge&quot;&gt;strtol()&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;If input meets the length constraint and can be interpreted as an integer, the loop ends.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;example-read-integer&quot;&gt;Example: Read Integer&lt;/h2&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// file: integer-input.h
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#ifndef INTEGER_INPUT_H
#define INTEGER_INPUT_H
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define MAX_DIGITS 12
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * This function removes surplus characters from the input buffer.
 * Otherwise, if more than the permitted number of characters have been entered during the
 * call to fgets(), the surplus characters (after MAX_DIGITS chars) remain in the input buffer
 * and will be wrongly accepted as input on the next iteration of the loop.
 * */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ClearInputBuffer&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Loop over input buffer and consume chars until buffer is empty
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EOF&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;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getIntegerFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputInteger&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_DIGITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;memset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&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;n&quot;&gt;MAX_DIGITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&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;c1&quot;&gt;// Note that fgets returns inputBuffer on success.
&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// This becomes important when freeing - free either `input` or
&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// `inputBuffer` to avoid an attempted double-free error.
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fgets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_DIGITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		
		&lt;span class=&quot;c1&quot;&gt;// If fgets() receives less than MAX_DIGITS, the last char in the array is '\n'.
&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Therefore if the last char is not '\n', too many characters were entered.
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&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;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[ERROR]: Too many characters: max input is %d chars.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_DIGITS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;ClearInputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;continue&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;c1&quot;&gt;// Check that the input can be intepreted as an integer
&lt;/span&gt;		&lt;span class=&quot;c1&quot;&gt;// Convert to integer using `strtol()`
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endptr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputInteger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strtol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		
		&lt;span class=&quot;c1&quot;&gt;// If an integer was not found, endptr remains set to input
&lt;/span&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endptr&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;c1&quot;&gt;// Remove trailing newline by adding NUL at the index of the
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// terminating '\n' character. See man strcspn - this function
&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;// gets the length of a prefix substring.
&lt;/span&gt;			&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strcspn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Invalid input: no integer found in %s.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[ERROR]: That doesn't look like an integer.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&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;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&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;cp&quot;&gt;#endif
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Example of usage:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// file: main.c
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &quot;integer-input.h&quot;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter integer:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;getIntegerFromStdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;You entered: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

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

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/problem-with-scanf-when-there-is-fgetsgetsscanf-after-it/&quot;&gt;scanf() leaves newline in buffer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/3302594/3590673&quot;&gt;Concise description&lt;/a&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt; vs &lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; (TLDR; use &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://c-faq.com/stdio/scanfprobs.html&quot;&gt;comp.lang.c list&lt;/a&gt; - &lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; problems re: stdin&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://c-faq.com/stdio/scanfhang.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;scanf()&lt;/code&gt; and whitespace&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/26583890/3590673&quot;&gt;Clean &amp;amp; compact description of &lt;code class=&quot;highlighter-rouge&quot;&gt;fgets()&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;strtol()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Fri, 31 May 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/05/Integer-Input-in-C/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/05/Integer-Input-in-C/</guid>
      </item>
      
    
      
      <item>
        <title>Conditional Printing in C and C++ Using a Ternary Statement</title>
        <description>&lt;p&gt;This article contrasts how output to stdout differs between C++ and C (&lt;code class=&quot;highlighter-rouge&quot;&gt;std::cout&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt;). In particular, we’re looking at conditional output that includes variables.&lt;/p&gt;

&lt;h2 id=&quot;c-stream-out-operator&quot;&gt;C++ Stream Out Operator&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator in C++ is the stream insertion operator and it is used to push data into the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::out&lt;/code&gt; output stream.&lt;/p&gt;

&lt;p&gt;This allows you to print to stdout like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;std::cout figures out how to output variables - you can just feed them in and it works automagically:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cheddar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The price of &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; is &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Outputs: The price of Cheddar is 10.99
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;the-printf-function&quot;&gt;The printf() Function&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt; function uses placeholders to insert variable values into a string for output to stdout:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cheddar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The price of %s is %f.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You need to be careful to use the correct conversion specifiers in the placeholder.
These are determined by the type of data to be inserted. In the example above, &lt;code class=&quot;highlighter-rouge&quot;&gt;%s&lt;/code&gt; denotes a string placeholder and &lt;code class=&quot;highlighter-rouge&quot;&gt;%f&lt;/code&gt; denotes a float placeholder.&lt;/p&gt;

&lt;p&gt;Python 3 gives you the best of both worlds with the string method &lt;code class=&quot;highlighter-rouge&quot;&gt;format()&lt;/code&gt;, which allows you to insert unspecified data types into placeholders within the output string.&lt;/p&gt;

&lt;h2 id=&quot;conditional-output&quot;&gt;Conditional Output&lt;/h2&gt;
&lt;p&gt;If you want to output content that is conditional, you can embed ternary statements within the C++ &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cout&lt;/code&gt; output stream:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Example of a simple ternary with output stream operators.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;We have cheese.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+++Out of Cheese Error+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you want to embed variables in your conditonal output stream, this method doesn’t work. As far as I can tell, you need to employ an if/else block.&lt;/p&gt;

&lt;p&gt;By way of contrast, it’s pretty easy to embed variables within a ternary statement using &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the following example the objective is to let the user know the level of cheese if the level of cheese is greater than zero, but to display a warning if the level of cheese is zero.&lt;/p&gt;

&lt;p&gt;The example is C++, but the &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt; statements are valid in C.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// This achieves what we need, but is pretty verbose:
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cheese level: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+++Out of Cheese Error+++&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Format string the same for both conditions - not a good solution
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// since '0' is printed in the empty case.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s%d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cheese level: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+++Out of Cheese Error+++&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	
	&lt;span class=&quot;c1&quot;&gt;// Better solution - choose the format string in a ternary statement
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Cheese level: %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+++Out of Cheese Error+++&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheese&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	
	&lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

</description>
        <pubDate>Wed, 22 May 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/05/Conditional-Printing-in-C-and-C++-Using-a-Ternary-Statement/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/05/Conditional-Printing-in-C-and-C++-Using-a-Ternary-Statement/</guid>
      </item>
      
    
      
      <item>
        <title>Copy to Clipboard in Vim under Ubuntu</title>
        <description>&lt;p&gt;To copy to clipboard in Vim under Ubuntu:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select a block to copy using Visual mode.&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;+y&lt;/code&gt; to yank to clipboard (instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;Y&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 02 May 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/05/Copy-to-Clipboard-in-Vim-under-Ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/05/Copy-to-Clipboard-in-Vim-under-Ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>C++ error ambiguating new declaration</title>
        <description>&lt;p&gt;If you receive a C++ compiler error message that includes the words “ambiguating new declaration”, check that you have the correct return type in your function declaration and definition.&lt;/p&gt;

&lt;h2 id=&quot;error-message&quot;&gt;Error Message&lt;/h2&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;g++ -W -Wall -std&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;c++17 -o bin/main IntArray.cpp main.cpp
IntArray.cpp: In &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; ‘void mySwap&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IntArray&amp;amp;, IntArray&amp;amp;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;’:
IntArray.cpp:77:37: error: ambiguating new declaration of ‘void mySwap&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IntArray&amp;amp;, IntArray&amp;amp;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;’
 void mySwap&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IntArray&amp;amp; a, IntArray&amp;amp; b&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                                     ^
In file included from IntArray.cpp:1:0:
IntArray.h:28:19: note: old declaration ‘IntArray&amp;amp; mySwap&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IntArray&amp;amp;, IntArray&amp;amp;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;’
  friend IntArray&amp;amp; mySwap&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;IntArray&amp;amp; a, IntArray&amp;amp; b&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;;
                   ^
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;cause&quot;&gt;Cause&lt;/h2&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// IntArray.h
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// wrong return type!
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IntArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mySwap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IntArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// IntArray.cpp
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IntArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IntArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;If you’re relatively new to C++ (or maybe just tired) you might miss this. It may not seem like the most obvious error message, but the caret in the second error really pinpoints the issue.&lt;/p&gt;

&lt;p&gt;In this case, the compiler has read the function declaration/definition in the file &lt;code class=&quot;highlighter-rouge&quot;&gt;IntArray.cpp&lt;/code&gt; and spotted a problem: “error: ambiguating new declaration…”.&lt;/p&gt;

&lt;p&gt;The declaration is incompatible with the declaration in the header file because the return type differs. The first error uses the word “new” because it can see the declaration has already been made (in the header file). This is not necessarily a problem - as function overloading involves re-declaring a function with different parameter types. However in this case, the return type differs - this is not part of function overloading, so the declarations differ and the compiler can’t make sense of what you need.&lt;/p&gt;

&lt;h2 id=&quot;cognition-attention--debugging&quot;&gt;Cognition, Attention &amp;amp; Debugging&lt;/h2&gt;
&lt;p&gt;It’s interesting that obvious bugs like this can trip you up.&lt;/p&gt;

&lt;p&gt;I think viewing the function declaration and definition at the same time helps. If the two files are in different tabs, you’re relying on your memory to reliably take a snapshot of the definition/declaration as you switch between files. I suspect that this is less reliable in terms of spotting bugs than viewing the header and implementation files side by side.&lt;/p&gt;

</description>
        <pubDate>Thu, 02 May 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/05/C++-error-ambiguating-new-declaration/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/05/C++-error-ambiguating-new-declaration/</guid>
      </item>
      
    
      
      <item>
        <title>Operator Overloading Custom Output Stream in C++</title>
        <description>&lt;p&gt;It can be useful to display data from a user-defined type (e.g. an object instantiated from a class) using the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cout&lt;/code&gt; object. This can be achieved by overloading the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;This would allow you to print selected data members in a meaningful way. For example, if you have a class &lt;code class=&quot;highlighter-rouge&quot;&gt;Point&lt;/code&gt; which holds data members &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;y&lt;/code&gt; to represent horizontal and vertical displacement, the following might be a useful way to display a &lt;code class=&quot;highlighter-rouge&quot;&gt;Point&lt;/code&gt; object:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Prints &quot;(10, 2)&quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You need to set up the insertion operator such that it accepts an &lt;code class=&quot;highlighter-rouge&quot;&gt;std::ostream&lt;/code&gt; object on the left and a user-defined type on the right. You achieve this by declaring the overloaded operator as a friend of the class. This allows the function to accept the required parameters, and provides access to private data within the class.&lt;/p&gt;

&lt;p&gt;The function is then defined as a free operator -i.e. not a member of a class.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Point.h
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Point.cpp
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &quot;Point.h&quot;
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Member function declarations
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&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;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&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;c1&quot;&gt;// Because this is a friend function, we have access to the object's private data
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Implementation in main.cpp:&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;99.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Output: (99.9, 2.3)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;dont-declare-the-operator-overload-as-a-member-of-the-class&quot;&gt;Don’t Declare the Operator Overload as a Member of the Class&lt;/h2&gt;
&lt;p&gt;If you declare the &lt;code class=&quot;highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; as a non-static data member - i.e. if it is declared in the class, accepting a &lt;code class=&quot;highlighter-rouge&quot;&gt;std::iostream&amp;amp;&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Point&lt;/code&gt; as parameters, it will cause a compiler error:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;g++ -W -Wall -std=c++17 -o bin/main Point.cpp main.cpp
In file included from Point.cpp:1:0:
Point.h:14:53: error: ‘std::ostream&amp;amp; Point::operator&amp;lt;&amp;lt;(std::ostream&amp;amp;, Point)’ must take exactly one argument
  std::ostream&amp;amp; operator&amp;lt;&amp;lt;(std::ostream&amp;amp; os, Point p);
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This occurs because:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A non-static member method takes an implicit &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; parameter that is passed as a hidden argument&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator takes exactly two arguments e.g. for &lt;code class=&quot;highlighter-rouge&quot;&gt;a &amp;lt;&amp;lt; b&lt;/code&gt;, the arguments are &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;b&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Declared as a member function, there are too many arguments!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn’t make logical sense for the overloaded &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt; operator to be a member function, since in it’s implementation it needs to get data from a passed in object and pass this along to the output stream.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TLDR;&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Declare the &lt;code class=&quot;highlighter-rouge&quot;&gt;operator&amp;lt;&amp;lt;&lt;/code&gt; as a friend of the class.&lt;/li&gt;
  &lt;li&gt;DO NOT define the function as a member of the class - define it as a free function outside the class.&lt;/li&gt;
  &lt;li&gt;The friend declaration ignores the private/public designators&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/standard-library/overloading-the-output-operator-for-your-own-classes?view=vs-2019&quot;&gt;Microsoft: Overloading the « Operator for Your Own Classes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/10745374/3590673&quot;&gt;Useful SO answer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 25 Apr 2019 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2019/04/Overloading-Output-Stream-in-C++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/04/Overloading-Output-Stream-in-C++/</guid>
      </item>
      
    
      
      <item>
        <title>Import Private Key from Bitcoin Paper Wallet to Bitcoin Core</title>
        <description>&lt;p&gt;Import a private key from a BIP38 encrypted Bitcoin paper wallet to a Bitcoin Core (Bitcoin-QT) client wallet.&lt;/p&gt;

&lt;p&gt;This article outlines how to import a &lt;a href=&quot;https://en.bitcoin.it/wiki/BIP_0038&quot;&gt;BIP38&lt;/a&gt; encrypted private key (for example, a Bitcoin paper wallet) to a Bitcoin Core wallet. This process allows the Bitcoin Core client to access and control the funds associated with the paper wallet Bitcoin address.&lt;/p&gt;

&lt;p&gt;The process is quite involved - and much of the online documentation is either incomplete or outdated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this article describes &lt;em&gt;importing&lt;/em&gt; rather than &lt;em&gt;sweeping&lt;/em&gt; the paper wallet.&lt;/p&gt;

&lt;h2 id=&quot;importing-vs-sweeping&quot;&gt;Importing vs Sweeping&lt;/h2&gt;
&lt;p&gt;Importing a private key hands control of the Bitcoins linked to the paper wallet to the Bitcoin Core client - the funds remain attached to the original Bitcoin address, as the private key is &lt;em&gt;only&lt;/em&gt; imported. As such, if others have access to the paper wallet private key, they would also be able to gain access to the funds.&lt;/p&gt;

&lt;p&gt;In contrast &lt;em&gt;sweeping&lt;/em&gt; the private key involves making a transaction whereby all Bitcoins held on the wallet are sent to a new address managed by the receiving client - leaving the original (paper) wallet empty, and the funds in the full and exclusive control of the Bitcoin client.&lt;/p&gt;

&lt;p&gt;The Bitcoin Core client does not have a built in function for ‘sweeping’ funds. Other wallets, such as the &lt;a href=&quot;https://electrum.org/#home&quot;&gt;Electrum&lt;/a&gt; desktop client, &lt;a href=&quot;https://github.com/mycelium-com/wallet&quot;&gt;Mycelium&lt;/a&gt; mobile wallet do have this function. I haven’t checked these.&lt;/p&gt;

&lt;h2 id=&quot;decrypting-the-private-key&quot;&gt;Decrypting the Private Key&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Access to the private key equates to full control of the funds attached to the Bitcoin address. Be careful not to expose the private key during the decryption &amp;amp; import process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decryption can be done using &lt;a href=&quot;https://www.bitaddress.org&quot;&gt;bitaddress.org&lt;/a&gt;. Download bitaddress.org and run locally after verifying the downloaded copy. For extra security (or added paranoia, depending on your viewpoint), run a verified copy of bitaddress.org in an offline &lt;a href=&quot;https://tails.boum.org/&quot;&gt;Tails&lt;/a&gt; session. You could use Tails along with a persistent encrypted data partition on a USB drive with any offline computer to generate/decrypt Bitcoin private keys.&lt;/p&gt;

&lt;p&gt;To decrypt the private key:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Download and verify a copy of bitaddress.org - e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;bitaddress.org-vX.X.X-SHA256-XXX.html&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;optional---for-extra-security&quot;&gt;Optional - for Extra Security&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Copy &lt;code class=&quot;highlighter-rouge&quot;&gt;bitaddress.org-vX.X.X-SHA256-XXX.html&lt;/code&gt; to a newly-formatted USB key&lt;/li&gt;
  &lt;li&gt;Disconnect computer from the internet&lt;/li&gt;
  &lt;li&gt;Boot into a &lt;a href=&quot;https://tails.boum.org/&quot;&gt;Tails&lt;/a&gt; session&lt;/li&gt;
  &lt;li&gt;Add encrypted persistent storage the the Tails USB drive&lt;/li&gt;
  &lt;li&gt;Store the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitaddress.org-vX.X.X-SHA256-XXX.html&lt;/code&gt; file in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/Persistent/Tor Browser/&lt;/code&gt; (Note that Tor restricts local file directories - location matters)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re certain that your system is secure (without malware or keyloggers etc), you could skip the previous steps and just disconnect from the internet. Personally, I take the time to run a verified bitaddress.org copy in an offline Tails session.&lt;/p&gt;

&lt;h3 id=&quot;common-actions&quot;&gt;Common Actions&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Navigate to a local copy of &lt;code class=&quot;highlighter-rouge&quot;&gt;bitaddress.org-vX.X.X-SHA256-XXX.html&lt;/code&gt; in a browser&lt;/li&gt;
  &lt;li&gt;Click “Wallet Details”&lt;/li&gt;
  &lt;li&gt;Enter the encrypted private key&lt;/li&gt;
  &lt;li&gt;Select “BIP38 Encrypt?”&lt;/li&gt;
  &lt;li&gt;Enter the encryption passphrase that was used to generate the encrypted key&lt;/li&gt;
  &lt;li&gt;Click “Decrypt BIP38”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The decryption output includes the Bitcoin address, as well as public and private keys in a wide range of formats, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Uncompressed Bitcoin Address&lt;/li&gt;
  &lt;li&gt;Compressed Bitcoin Address&lt;/li&gt;
  &lt;li&gt;Public Key Uncompressed (130 characters [0-9A-F])&lt;/li&gt;
  &lt;li&gt;Public Key Compressed (66 characters [0-9A-F])&lt;/li&gt;
  &lt;li&gt;Private Key Hexadecimal Format (64 characters [0-9A-F])&lt;/li&gt;
  &lt;li&gt;Private Key Base64 (44 characters)&lt;/li&gt;
  &lt;li&gt;Private Key BIP38 Format (58 characters base58, starts with ‘6P’) - the original encrypted key&lt;/li&gt;
  &lt;li&gt;Private Key, Wallet Import Format&lt;/li&gt;
  &lt;li&gt;Private Key, Wallet Import Format Compressed - &lt;em&gt;this is probably what you need&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;compressed-vs-uncompressed-addressprivate-key&quot;&gt;Compressed vs Uncompressed Address/Private Key&lt;/h2&gt;
&lt;p&gt;Both compressed and uncompressed Bitcoin addresses are generated from the public key. The compressed version of the public key is almost half the size, and generates a Bitcoin address that is &lt;em&gt;distinct&lt;/em&gt; from the uncompressed public key.&lt;/p&gt;

&lt;p&gt;Because compressing keys significantly reduces blockchain space without losing any data, compressed keys are the recommended default.&lt;/p&gt;

&lt;p&gt;To access funds, the compression state of the keys must match. If you’ve sent funds to the Bitcoin Address generated from the compressed public key, you’ll need to import the compressed Private Key (i.e Wallet Import Format compressed).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you generated your paper wallet using bitaddress.org, the Bitcoin addresses on the paper wallet are compressed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This means that you need to import the &lt;em&gt;Private Key WIF Compressed&lt;/em&gt;. This address has 52 base58 characters and starts with a ‘K’ or ‘L’.&lt;/p&gt;

&lt;p&gt;If you accidentally import the uncompressed private key, you’ll probably see a balance of zero. This doesn’t mean you’ve lost funds - you would have sent funds to the &lt;em&gt;compressed&lt;/em&gt; address, and you therefore need to import the compressed private key.&lt;/p&gt;

&lt;h2 id=&quot;importing-the-private-key&quot;&gt;Importing The Private Key&lt;/h2&gt;
&lt;p&gt;This is accomplished with the &lt;code class=&quot;highlighter-rouge&quot;&gt;importprivkey&lt;/code&gt; command in the Bitcoin Core CLI. This command adds a private key to your wallet - it would also serve to import a private key as created by the &lt;code class=&quot;highlighter-rouge&quot;&gt;dumpprivkey&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;importprivkey&lt;/code&gt; command has the format:
importprivkey “Kthebitcoinprivkey” ( “label” ) ( rescan )&lt;/p&gt;

&lt;p&gt;Arguments:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;“bitcoinprivkey” (string, required) The private key (see dumpprivkey)&lt;/li&gt;
  &lt;li&gt;“label” (string, optional, default=””) An optional label&lt;/li&gt;
  &lt;li&gt;rescan (boolean, optional, default=true) Rescan the wallet for transactions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: This call can take minutes to complete if rescan is true.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Dump a private key&lt;/span&gt;
bitcoin-cli dumpprivkey &lt;span class=&quot;s2&quot;&gt;&quot;myaddress&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Import the private key with rescan&lt;/span&gt;
bitcoin-cli importprivkey &lt;span class=&quot;s2&quot;&gt;&quot;privatekey&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Import using a label and without rescan&lt;/span&gt;
bitcoin-cli importprivkey &lt;span class=&quot;s2&quot;&gt;&quot;privatekey&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;testing&quot;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Import using default blank label and without rescan&lt;/span&gt;
bitcoin-cli importprivkey &lt;span class=&quot;s2&quot;&gt;&quot;privatekey&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# As a JSON-RPC call&lt;/span&gt;
curl --user myusername --data-binary &lt;span class=&quot;s1&quot;&gt;'{&quot;jsonrpc&quot;: &quot;1.0&quot;, &quot;id&quot;:&quot;curltest&quot;, &quot;method&quot;: &quot;importprivkey&quot;, &quot;params&quot;: [&quot;mykey&quot;, &quot;testing&quot;, false] }'&lt;/span&gt; -H &lt;span class=&quot;s1&quot;&gt;'content-type: text/plain;'&lt;/span&gt; http://127.0.0.1:8332/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Bitcoin_Core&quot;&gt;Bitcoin Core: Wikipedia&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/How_to_import_private_keys&quot;&gt;Bitcoin Core Wiki on Importing Private Keys&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitcoin.org/en/developer-guide#public-key-formats&quot;&gt;Public Key Formats: Developer Guide&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;See: https://www.reddit.com/r/BitcoinBeginners/comments/3yxiha/compressed_uncompressed_not_the_same_wallet/cyhhzrw/&quot;&gt;Discussion on Compressed vs Uncompressed Addresses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 03 Mar 2019 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2019/03/restore-key-from-bitcoin-paper-wallet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2019/03/restore-key-from-bitcoin-paper-wallet/</guid>
      </item>
      
    
      
      <item>
        <title>Strings in C</title>
        <description>&lt;p&gt;In C, strings are arrays of characters terminated by an ASCII NUL character &lt;code class=&quot;highlighter-rouge&quot;&gt;'\0'&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A string is a contiguous sequence of characters terminated by and including the first null character. The term multibyte string is sometimes used instead to emphasize special processing given to multibyte characters contained in the string or to avoid confusion with a wide string. A pointer to a string is a pointer to its initial (lowest addressed) character. The length of a string is the number of bytes preceding the null character and the value of a string is the sequence of the values of the contained characters, in order.&lt;/p&gt;

  &lt;p&gt;–&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#%5B%7B%22num%22%3A425%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C-27%2C816%2Cnull%5D&quot; title=&quot;Definition of string, ISO/IEC 9899:2011 WG14 draft version&quot;&gt;C11 ISO/IEC 9899:2011 Definition of string&lt;/a&gt; (p 180)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;string-initialisation&quot;&gt;String Initialisation&lt;/h2&gt;
&lt;p&gt;Strings can be declared as an array of characters or as a pointer to a character. In either case, a character string literal can be used to initialise the value.&lt;/p&gt;

&lt;p&gt;String literals are a collection of characters surrounded by double quotes. The terminating ‘\0’ character is implicit.&lt;/p&gt;

&lt;h2 id=&quot;string-declared-as-character-array&quot;&gt;String Declared as Character Array&lt;/h2&gt;
&lt;p&gt;For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Declare an empty string, big enough for 5 characters
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;An array declared to have 6 characters in this way can only store 5 actual characters - one element must be reserved for the termination character.&lt;/p&gt;

&lt;p&gt;A string can also be declared by initialising with a string literal:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This defines an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt; objects, whose elements are initialised with a character string literal (with an implicit null terminating character).&lt;/p&gt;

&lt;p&gt;In a similar way, you can also initialise with a comma separated list - note that you need to explicitly add the null character in this case:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;'A'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'l'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'i'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;char-array-objects-are-mutable&quot;&gt;Char Array Objects are Mutable&lt;/h3&gt;
&lt;p&gt;String literals defined as arrays (&lt;code class=&quot;highlighter-rouge&quot;&gt;char name[] = &quot;Mary&quot;&lt;/code&gt;) are stored in the stack can be modified.
If a string literal was declared as a char array, you can dereference and amend elements.&lt;/p&gt;

&lt;p&gt;Change the value stored in &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; from “Alice” to “Alina”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Amending a character array defined string is OK
// -----------------------------------------------
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Modifying a string defined as a character pointer is NOT OK
// The following will compile but results in undefined behaviour.
// The result will probably be a segmentation fault
// ------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;David&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;name2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// DON'T DO THIS IF NAME IS DEFINED AS A CHARACTER POINTER
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'\0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;string-declared-as-pointer-to-char&quot;&gt;String Declared as Pointer to Char&lt;/h2&gt;
&lt;p&gt;You can also define a string as a pointer to a char, initialised by a string literal. In this case, string literals are stored in a read only section of memory and are effectively constant.
For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, the value is stored in a read-only section in the binary file and cannot be modified. If you compile to an assembly file (use the &lt;code class=&quot;highlighter-rouge&quot;&gt;-S&lt;/code&gt; compiler option in gcc), you can see the string literals in the &lt;code class=&quot;highlighter-rouge&quot;&gt;.rodata&lt;/code&gt; section. In this context, rodata means “read-only data”.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-assembly&quot; data-lang=&quot;assembly&quot;&gt;/* main.s */
.file	&quot;main.c&quot;
.section	.rodata
.LC0:
.string	&quot;Bob&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Though the string literal is read-only, you can modify your &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; string by pointing it to a different string literal. Following on from the above example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// First Definition
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Redefine the char pointer
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Bub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assignment&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;will&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;see&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;both&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;literals&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;your&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can declare a variable as a pointer to a character without specifying the string length &amp;amp; location. For example: &lt;code class=&quot;highlighter-rouge&quot;&gt;char *name;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can then dynamically allocate memory to the string later.&lt;/p&gt;

&lt;h2 id=&quot;string-declaration-isoiec-9899201x&quot;&gt;String Declaration: ISO/IEC 9899:201x&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;The declaration &lt;code class=&quot;highlighter-rouge&quot;&gt;char s[] = &quot;abc&quot;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;t[3] = &quot;abc&quot;&lt;/code&gt;; defines “plain” &lt;code class=&quot;highlighter-rouge&quot;&gt;char array&lt;/code&gt; objects &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;t&lt;/code&gt; whose elements  are initialized with character string literals. This declaration is identical to &lt;code class=&quot;highlighter-rouge&quot;&gt;char s[] = { 'a', 'b', 'c', '\0' }&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;t[] = { 'a', 'b', 'c' }&lt;/code&gt;; The contents of the arrays are modifiable.&lt;/p&gt;

  &lt;p&gt;On the other hand, the declaration &lt;code class=&quot;highlighter-rouge&quot;&gt;char *p = &quot;abc&quot;;&lt;/code&gt; defines &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt; with type “pointer to char” and initializes it to  point to an object with type “array of char” with length 4 whose elements are initialized with a character string literal.&lt;/p&gt;

  &lt;p&gt;If an attempt is made to use &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt; to modify the contents of the array, the behavior is undefined.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf&quot;&gt;C11 ISO/IEC 9899:2011 Section 6.7.9&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf&quot;&gt;C11 ISO/IEC 9899:2011&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 29 Aug 2018 14:49:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/08/strings-in-c/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/08/strings-in-c/</guid>
      </item>
      
    
      
      <item>
        <title>C++ Namespace Template Functions</title>
        <description>&lt;p&gt;If you define a C++ template function in a namespace, the function definition needs to go in the header - not the &lt;code class=&quot;highlighter-rouge&quot;&gt;.cpp&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// utilities.h
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;vector&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &quot;Employee.hpp&quot;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utilities&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Function declaration - this function can be defined in utilities.cpp
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employeesReport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;staff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Template function must be defined in utilities.h
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collection&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You could also put the implementation in .cpp and include this file from within the header file.&lt;/p&gt;

&lt;h2 id=&quot;why&quot;&gt;Why?&lt;/h2&gt;
&lt;p&gt;Template functions are not real functions - they are turned into a real function by the compiler when it encounters a use of the function.&lt;/p&gt;

&lt;p&gt;This means that the template definition needs to be in the same scope as the call to the function. If the function is called in &lt;code class=&quot;highlighter-rouge&quot;&gt;main.cpp&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;utilities.h&lt;/code&gt; is included in this file, then the template must be defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;utilities.h&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/3040706/3590673&quot;&gt;SO answer with good explanation&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Wed, 22 Aug 2018 19:10:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/08/c++-namespace-template-functions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/08/c++-namespace-template-functions/</guid>
      </item>
      
    
      
      <item>
        <title>Radix 64 Encoding: Implementation in C</title>
        <description>&lt;p&gt;Radix 64 or base 64 is a binary-to-text encoding system that is designed to allow binary data to be represented in ASCII string format. This is an educational project accepts a string from a user and Radix 64 encodes it.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://github.com/DavidCWebs/radix-64-encoding&quot;&gt;GitHub repo accompanies this post&lt;/a&gt;, with a working example in C.&lt;/p&gt;

&lt;h2 id=&quot;what-is-radix-64-encoding&quot;&gt;What is Radix 64 Encoding?&lt;/h2&gt;
&lt;p&gt;Radix 64 encoding allows binary data stored in octets (i.e. bytes) to be expressed as printable characters.&lt;/p&gt;

&lt;p&gt;Radix-64 characters require the binary input to be split into blocks of 6. These numbers (which all range from 0 - 63) are then mapped onto a character set of printable characters.&lt;/p&gt;

&lt;p&gt;The Radix 64 characterset includes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A-Z&lt;/li&gt;
  &lt;li&gt;a-z&lt;/li&gt;
  &lt;li&gt;0-9&lt;/li&gt;
  &lt;li&gt;The additional characters ‘+’ and ‘/’&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This amounts to a total of 64 symbols. To encode binary data into Radix 64, data is parsed in 6-bit blocks (i.e. such that each block has a maximum value of 64), and the number represented by each 6-bit block is used to look up a Radix 64 character.&lt;/p&gt;

&lt;h2 id=&quot;number-of-output-bytes&quot;&gt;Number of Output Bytes&lt;/h2&gt;
&lt;p&gt;Radix 64 encoding results in 33% more bytes - every 3 input bytes is converted to 4 output.&lt;/p&gt;

&lt;p&gt;Given &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; input bytes, the output will be:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;4⌈n/3⌉&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The ceiling brackets &lt;code class=&quot;highlighter-rouge&quot;&gt;⌈x⌉&lt;/code&gt; mean round the number to the upper integer. In words, this expression would be:&lt;/p&gt;

&lt;p&gt;“The number of output characters is n divided by 3, rounded up to the next whole number and then multiplied by 4”.&lt;/p&gt;

&lt;h2 id=&quot;example-pgp-messages&quot;&gt;Example: PGP Messages&lt;/h2&gt;
&lt;p&gt;A good example is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Binary-to-text_encoding#ASCII_armor&quot;&gt;ascii-armor&lt;/a&gt; output from PGP:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jA0ECgMCl9ViayBOZkZg0kkBDqU+4ofR+bJDXd+cpfAQCk30pFcK4QmtFXYivhqy
N8WrBUN8ala9bJ8ON2+COaB1ls+Pr9ohpiWSQLlC6t6/fQLSsHFLCJq5
=GH0r
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The above example is the ciphertext (excluding cleartext message headers) that results from ASCII armored symmetric encryption of the string “Hello World!” (additional metadata is added by PGP - including a salt and the cipher algorithm designator).&lt;/p&gt;

&lt;p&gt;Note that the encrypted message consists of Radix 64 characters exclusively, with the ‘=’ sign used as padding - so in the message above, data after the ‘=’ is not part of the message. You wouldn’t see this padding if the number of the plaintext bytes was an exact multiple of three (and therefore did not require padding).&lt;/p&gt;

&lt;p&gt;By definition, each byte of the original ciphertext was a number from 0-255. Some of these numbers do not map to printable ASCII characters. Encoding the message as Radix 64 allows the message to be printed and/or sent as an email or text message - modes of communication which do not allow the transfer of binary data.&lt;/p&gt;

&lt;h2 id=&quot;the-radix-64-alphabet&quot;&gt;The Radix 64 Alphabet&lt;/h2&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Index R64 value  Index R64 value  Index R64 value  Index R64 value
0     A          17    R          34    i          51   z
1     B          18    S          35    j          52   0
2     C          19    T          36    k          53   1
3     D          20    U          37    l          54   2
4     E          21    V          38    m          55   3
5     F          22    W          39    n          56   4
6     G          23    X          40    o          57   5
7     H          24    Y          41    p          58   6
8     I          25    Z          42    q          59   7
9     J          26    a          43    r          60   8
10    K          27    b          44    s          61   9
11    L          28    c          45    t          62   +
12    M          29    d          46    u          63   /
13    N          30    e          47    v
14    O          31    f          48    w         (pad) =
15    P          32    g          49    x
16    Q          33    h          50    y
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;example-radix-64-encoding&quot;&gt;Example Radix 64 Encoding&lt;/h2&gt;
&lt;p&gt;Radix 64 encoding can be difficult to get your head around. Before building a programme to do the encoding, it can help to step through the process manually.&lt;/p&gt;

&lt;p&gt;This example will encode the string ‘david’ into Radix 64.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The string is represented by 5 chars.&lt;/li&gt;
  &lt;li&gt;The total size in bits (assuming that one char == 1 byte) is given by 8 x 5 = 40 bits.&lt;/li&gt;
  &lt;li&gt;Dividing the total number of bits by 6 leaves remainder 4 -  therefore 7 sextuplets will be needed to represent the string in Radix 64&lt;/li&gt;
  &lt;li&gt;The last sextuplet will have 2 bits of padding. When this is the case, ‘=’ padding character is added.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                +-----------+-----------+-----------+-----------+-----------+
char:           | 'd'       | 'a'       | 'v'       | 'i'       | 'd'       |
                +-----------+-----------+-----------+-----------+-----------+
binary:         | 011001 00 | 0110 0001 | 01 110110 | 011010 01 | 0110 0100 |
                |                                                           |
6 bit groups:   | 011001 | 000110 | 000101 | 110110 | 011010 | 010110 | 0100  | 00  |
Decimal output: | 25     | 6      | 5      | 54     | 26     | 22     | 16    |     |
                +--------+--------+--------+--------+--------+--------+-------+-----+
Radix-64 chars  | Z      | G      | F      | 2      | a      | W      | Q     | =   |
                +--------+--------+--------+--------+--------+--------+-------+-----+
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;radix-64-encoding-in-c&quot;&gt;Radix 64 Encoding in C&lt;/h2&gt;
&lt;p&gt;The encoding takes place in the function &lt;code class=&quot;highlighter-rouge&quot;&gt;base64Encode()&lt;/code&gt;, defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;base64.c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The function receives:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The input buffer &lt;code class=&quot;highlighter-rouge&quot;&gt;inputBuffer&lt;/code&gt; - which is a pointer to a character array (a c-style string) that contains the user input&lt;/li&gt;
  &lt;li&gt;The output buffer &lt;code class=&quot;highlighter-rouge&quot;&gt;b64Buffer&lt;/code&gt; - a pointer to a dynamically allocated section of memory, sufficient to contain the Radix 64 encoded output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the first character, the function:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Takes the first 6 bits, looks up the value against the Radix 64 encoding and assigns the correct ASCII character to &lt;code class=&quot;highlighter-rouge&quot;&gt;b64Buffer[0]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;A temporary byte is then created wich stores the data from the unused bits (i.e. the least significant 2 bits from the first char is stored as the most significant 2 bits in &lt;code class=&quot;highlighter-rouge&quot;&gt;tmpByte&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;A &lt;code class=&quot;highlighter-rouge&quot;&gt;size_t divider&lt;/code&gt; variable is set - this will determine the number of bits to take from the next char - these will be combined with the bits in &lt;code class=&quot;highlighter-rouge&quot;&gt;tmpByte&lt;/code&gt; to form the next Radix 64 6-bit group&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bitwise-operations&quot;&gt;Bitwise Operations&lt;/h3&gt;
&lt;p&gt;Bitwise operators allow for bit-by-bit manipulation of data stored in individual bytes.&lt;/p&gt;

&lt;p&gt;In our case, we make use of bit-masking to collect bits from specific positions within a byte:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// base64.c
// Handling the first char
// ----------------------
// tmpByte will carry unused bits forward
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// We need last 2 bits, so mask against 00000011
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputBuffer&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;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Mask is 11111100 - note usefulness of the complement operator!
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// After getting the first 6 bits, shift them
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookupVal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&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;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Get the b64 character
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64Buffer&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encodingTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lookupVal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// First run: set the divider for next char
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Originally I gathered the first 6 bits like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookupVal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&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;o&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…which bit shifts the original char (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;inputBuffer[0]&lt;/code&gt;) two places to the right before masking against &lt;code class=&quot;highlighter-rouge&quot;&gt;00111111&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This does collect the correct data for the Radix 64 lookup index - but it has the unwanted side-effect of mutating the original char - which meant that the function signature could not declare &lt;code class=&quot;highlighter-rouge&quot;&gt;inputBuffer&lt;/code&gt; as &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, the function loops through the characters. During each iteration:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The correct bits are used to determine the next radix 64 character&lt;/li&gt;
  &lt;li&gt;Excess bits are stored in &lt;code class=&quot;highlighter-rouge&quot;&gt;tmpByte&lt;/code&gt; to be carried forward if necessary&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;divider&lt;/code&gt; is set such that the correct number of bits are collected when advancing&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Loop to the penultimate character (assuming last char is a newline)
// The last 2 bits of tmpByte is the last 2 bits of the first char
// -------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputLength&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;c1&quot;&gt;// Shift bits from previous iteration to the correct position
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Mask representing the first `divider` bits of a byte
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Collect the first `divider` bits of the current char
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mostSigBits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Shift to correct position
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;mostSigBits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Add combined bytes to the return buffer
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;b64Buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encodingTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mostSigBits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// If the divider == 2, the rest of this byte shoudl form the next radix 64 char.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Set the last 6 bits of this char as a new radix 64 character
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;n&quot;&gt;b64Buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encodingTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// In this case, there is no data to carry forward
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Carry forward the unused bits from the current character
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// Apply a logical &amp;amp; against a mask of the last bits
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&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;c1&quot;&gt;// Set divider for the next char
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// Add the remaining data from the tmpByte
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64Buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bufIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encodingTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tmpByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The divider is set &lt;code class=&quot;highlighter-rouge&quot;&gt;divider = (divider - 2) ? divider - 2 : 6;&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;If the current divider is 2, set divider to 6 (because no data is carried forward from the current character)&lt;/li&gt;
  &lt;li&gt;If the divider is not 2, set the divider to divider - 2:
    &lt;ul&gt;
      &lt;li&gt;Current divider is 4, 4 bits carried forward, new divider is 2&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;notes-on-decoding&quot;&gt;Notes on Decoding&lt;/h2&gt;
&lt;p&gt;To decode radix 64 encoded text, typically four characters are converted to three bytes. If the string contains a single padding character (i.e. ‘=’) the last four characters (including the padding character) will decode to only two bytes, while ‘==’ indicates that the four characters will decode to only a single byte. From &lt;a href=&quot;https://tools.ietf.org/html/rfc1421&quot;&gt;RFC 1521&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Since all base64 input is an integral number of octets, only the following cases can arise:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no ‘=’ padding&lt;/li&gt;
    &lt;li&gt;the final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two ‘=’ padding characters&lt;/li&gt;
    &lt;li&gt;the final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one ‘=’ padding character.”&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Manual example:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;radix 64 chars  | T | Q | = | =  |
TQ== goes to a single byte
radix 64 int:   | 19  | 16  |
binary:         | 010011 | 010000 |
First 8 bits:   | 01001101 | last 4 bits are &quot;padding&quot; zeroes
Decimal:        | 77 |
ASCII:          | M  |
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/radix-64-encoding&quot;&gt;GitHub repo&lt;/a&gt; with sample code&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;Wiki article&lt;/a&gt;: Base 64 encoding&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.ietf.org/html/rfc1421&quot;&gt;RFC 1421&lt;/a&gt;: Privacy Enhancement for Internet Electronic Mail: Part I: Message Encryption and Authentication Procedures&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Binary-to-text_encoding#ASCII_armor&quot;&gt;ASCII armor in PGP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 21 Aug 2018 20:09:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/08/radix-64-encoding-with-example-implementation-in-c/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/08/radix-64-encoding-with-example-implementation-in-c/</guid>
      </item>
      
    
      
      <item>
        <title>Double Pointers and Linked List in C</title>
        <description>&lt;p&gt;This article will (hopefully) demonstrate the usefulness of double pointers (multiple indirection) in manipulating linked list elements efficiently.&lt;/p&gt;

&lt;h2 id=&quot;intro-to-linked-lists&quot;&gt;Intro to Linked Lists&lt;/h2&gt;
&lt;p&gt;A linked list is an abstract data structure that is made up of a collection of nodes (or elements). Lists nodes are accessed by means of &lt;a href=&quot;https://en.wikipedia.org/wiki/Sequential_access&quot;&gt;sequential access&lt;/a&gt; - they are accessed in an ordered/predetermined sequence.&lt;/p&gt;

&lt;p&gt;List objects can be stored anywhere in memory - they do not need to be next to one another. This makes it easy to insert new elements, but has the disadvantage of requiring sequential access when accessing values.&lt;/p&gt;

&lt;h2 id=&quot;linked-list-using-double-pointers&quot;&gt;Linked List Using Double Pointers&lt;/h2&gt;
&lt;p&gt;For the current example, nodes are dynamically allocated (using &lt;code class=&quot;highlighter-rouge&quot;&gt;malloc()&lt;/code&gt;) and each node consists of a data field and a reference (a pointer) to the next node in the list. In the case of the last node in the list, the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field contains &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt; - it is set as a null pointer.&lt;/p&gt;

&lt;p&gt;Our nodes are defined with a C struct - for the purposes of this exercise, nodes are defined as &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt; using &lt;code class=&quot;highlighter-rouge&quot;&gt;typedef&lt;/code&gt;. The data field of the node consists of a single &lt;code class=&quot;highlighter-rouge&quot;&gt;char *name&lt;/code&gt; member variable:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// list.h
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&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;n&quot;&gt;NODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After this &lt;code class=&quot;highlighter-rouge&quot;&gt;typedef&lt;/code&gt; declaration, &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE *head&lt;/code&gt; defines a variable &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; which is a pointer to a node struct pointer.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity this example will consider two actions:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt;: add a node to the start (head) of the list&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;append()&lt;/code&gt;: add a node at the end of the list&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;pointers&quot;&gt;Pointers&lt;/h2&gt;
&lt;p&gt;A pointer is a variable that stores the memory address of another variable. In C, you need to define the type of the object that is being pointed at.&lt;/p&gt;

&lt;p&gt;For example: &lt;code class=&quot;highlighter-rouge&quot;&gt;int a = 42; int *pNum = &amp;amp;a;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The variable &lt;code class=&quot;highlighter-rouge&quot;&gt;pNum&lt;/code&gt; now contains the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt;, which is the memory location of an object having the data type integer. Dereferencing the pointer variable &lt;code class=&quot;highlighter-rouge&quot;&gt;*pNum&lt;/code&gt; instructs the programme to return the integer value that is held at the memory address returned by &lt;code class=&quot;highlighter-rouge&quot;&gt;pNum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; you shouldn’t try to dereference a null pointer in C - this produces undefined behaviour.&lt;/p&gt;

&lt;h2 id=&quot;initialise-the-linked-list&quot;&gt;Initialise the Linked List&lt;/h2&gt;
&lt;p&gt;The list is initialised by creating a &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE *head&lt;/code&gt; which is set to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;. The variable &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; is now a pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;, but as &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;s are added to the list &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; will be set to point to the first &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;. In this way, &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; becomes the access point for sequential access to the list.&lt;/p&gt;

&lt;h2 id=&quot;adding-nodes&quot;&gt;Adding Nodes&lt;/h2&gt;
&lt;p&gt;As the first node is added, the head pointer is amended to point to the new node, and the next pointer of the new node points to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;. In the case of the first node, &lt;code class=&quot;highlighter-rouge&quot;&gt;append()&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; have exactly the same effect.&lt;/p&gt;

&lt;p&gt;In each case, a node needs to be created. To achieve this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Function to create a node and return a pointer to the node.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;createNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&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;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// This will be set on insertion
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;why-double-pointers&quot;&gt;Why Double Pointers?&lt;/h2&gt;
&lt;p&gt;Arguments are always passed to functions &lt;strong&gt;by value&lt;/strong&gt; in C. In other words, when C passes control to a function, a copy of each argument is made and this copy is passed to the function - leaving the original variable unchanged.&lt;/p&gt;

&lt;p class=&quot;emphasis-block&quot;&gt;In order to amend a variable in a calling function from within a called function, you need to pass a pointer to the variable as a function argument. This provides the called function with the memory address of the variable to be amended. Dereferencing this (pointer) variable within the called function provides access to the original value.&lt;/p&gt;

&lt;p&gt;Simplified example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Function argument is the memory address of input, NOT the actual variable
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doubleInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&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;c1&quot;&gt;// Dereference the pointer to provide access:
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// *input refers the the value held by the memory address input.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// By dereferencing the address, we can directly amend what is stored there
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// from within the function.
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&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;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myNum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myNum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs 5
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doubleInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myNum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Pass the address of myNum to doubleInput()
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myNum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs 10
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;prepend&quot;&gt;Prepend&lt;/h2&gt;
&lt;p&gt;In the function definition for &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; shown below, the first parameter is &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE **head&lt;/code&gt;. This specifies that the function receives a variable with the &lt;strong&gt;pointer to pointer&lt;/strong&gt; variable type &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE **&lt;/code&gt;. In other words, the function receives an address of a variable which is in turn a pointer to a &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;- in this case, the function argument is the address of the variable &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE *head&lt;/code&gt; which is a pointer that points to either the first node in the list or to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If a new node is added to the head of the list (by means of a &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; action), the head pointer is amended to point to the new node and the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field of the new node refers to the address of the second (previously first) node.&lt;/p&gt;

&lt;p&gt;This is the easier function to understand:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// The caller
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Prepend node with the name &quot;Goldfish&quot;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prependNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;createNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Goldfish&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;prependNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newNode&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;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the case of the new node being the first node in the list, &lt;code class=&quot;highlighter-rouge&quot;&gt;head == NULL&lt;/code&gt; so the assignment &lt;code class=&quot;highlighter-rouge&quot;&gt;newNode-&amp;gt;next = *head&lt;/code&gt; correctly sets the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field of the last node (in this case, also the first node) to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the list already contains nodes, the &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; variable holds a pointer to a pointer to the existing first node. Note that the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; is passed into the &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; function from the caller.&lt;/p&gt;

&lt;p&gt;Because we want to insert the new node before the existing first node, the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field of the new node should point to the address of the existing first node. The declaration &lt;code class=&quot;highlighter-rouge&quot;&gt;newNode-&amp;gt;next = *head&lt;/code&gt; correctly makes this assignment.&lt;/p&gt;

&lt;p&gt;Setting the new &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; reference is where double pointers become useful. Because we pass in the address of the head variable rather than the variable itself, we can access (and amend) it’s value from within the &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; function. When the &lt;code class=&quot;highlighter-rouge&quot;&gt;*head&lt;/code&gt; is set to the address of the new node from within &lt;code class=&quot;highlighter-rouge&quot;&gt;prepend()&lt;/code&gt; we are saying:&lt;/p&gt;

&lt;p class=&quot;emphasis-block&quot;&gt;“Dereference &lt;code class=&quot;highlighter-rouge&quot;&gt;**head&lt;/code&gt; once to get the memory address that is held by &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt; in the calling function, and set this address to the address of the new node.”&lt;/p&gt;

&lt;h2 id=&quot;append-node&quot;&gt;Append Node&lt;/h2&gt;
&lt;p&gt;If a new node is added to the end of the list (by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;append()&lt;/code&gt;, the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field of the previously last node is amended to point to the memory address of the new node. If the appended node is also the first node in the list, then the head pointer must be amended to point to the new node.&lt;/p&gt;

&lt;p&gt;In this case, the challenge is to efficiently find the last node, whilst accounting for the possibility that this may be the first node in the list. Note that in any case the &lt;code class=&quot;highlighter-rouge&quot;&gt;next&lt;/code&gt; field of the new node points to null.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headRef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newNode&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;n&quot;&gt;NODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tracer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headRef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tracer&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;n&quot;&gt;tracer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tracer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&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;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tracer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tracer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create a tracer and set this initially to hold the memory address of head. Set &lt;code class=&quot;highlighter-rouge&quot;&gt;tracer&lt;/code&gt; to the address of the pointer to the next &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;. In the case of an empty list or the last &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;, this value will be &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;NOTE: &lt;code class=&quot;highlighter-rouge&quot;&gt;*tracer&lt;/code&gt; dereferences &lt;code class=&quot;highlighter-rouge&quot;&gt;tracer&lt;/code&gt; once, so it refers to a pointer to a &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The arrow operator can then be used to indirectly access the member variable. The following are equivalent:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tracer = &amp;amp;(*tracer)-&amp;gt;next;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tracer = &amp;amp;(*(*tracer)).next;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tracer = &amp;amp;(**tracer).next;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;tracer&lt;/code&gt; must be a pointer to a pointer to a &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt; - it must contain the memory address of a pointer to a &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt; (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE *&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;After the loop, &lt;code class=&quot;highlighter-rouge&quot;&gt;*tracer&lt;/code&gt; will be a pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt; even if the list is empty.
&lt;code class=&quot;highlighter-rouge&quot;&gt;*tracer&lt;/code&gt; now refers to the pointer to the next node of the last node. Currently &lt;code class=&quot;highlighter-rouge&quot;&gt;NULL&lt;/code&gt;, the next line refers it to the new &lt;code class=&quot;highlighter-rouge&quot;&gt;NODE&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Struct_(C_programming_language)&quot;&gt;struct (C Programming Language)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Sequential_access&quot;&gt;Sequential Access&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Linked_list#Tradeoffs&quot;&gt;Pros and cons of linked lists&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 23 Jul 2018 14:53:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/07/double-pointers-and-linked-list-in-c/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/07/double-pointers-and-linked-list-in-c/</guid>
      </item>
      
    
      
      <item>
        <title>First &amp; Last Element in C++ Iterator Loop</title>
        <description>&lt;p&gt;Iterator-based iteration in C++ works for all containers, including lists and associative containers.&lt;/p&gt;

&lt;p&gt;When looping with an iterator, the index of the current iteration isn’t immediately obvious, unless you resort to incrementing a counter.&lt;/p&gt;

&lt;h2 id=&quot;first-element&quot;&gt;First Element&lt;/h2&gt;
&lt;p&gt;It’s pretty straightforward to get the first element - you just compare the iterator at the current iteration through &lt;code class=&quot;highlighter-rouge&quot;&gt;container&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;container.begin()&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;last-element&quot;&gt;Last Element&lt;/h2&gt;
&lt;p&gt;To get the last element in an iterator loop you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;std::next()&lt;/code&gt; (from C++11). The loop is generally terminated by &lt;code class=&quot;highlighter-rouge&quot;&gt;iterator != container.end()&lt;/code&gt;, where &lt;code class=&quot;highlighter-rouge&quot;&gt;end()&lt;/code&gt; returns an iterator that points to the &lt;em&gt;past-the-end&lt;/em&gt; element. If &lt;code class=&quot;highlighter-rouge&quot;&gt;container.next(iterator) == container.end()&lt;/code&gt; returns true, you’re on the last element.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;map&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rocky&quot;&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Ronnie&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;const_iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// Test for first element
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;| &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; = &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Test for last element
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; |&quot;&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Output:
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rocky&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;Ronnie&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/iterator/end/&quot;&gt;C++ reference: &lt;code class=&quot;highlighter-rouge&quot;&gt;std::end&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/14374550/3590673&quot;&gt;Comparison of Looping Methods, Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 19 Jul 2018 14:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/07/first-&amp;-last-element-in-c++-iterator-loop/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/07/first-&amp;-last-element-in-c++-iterator-loop/</guid>
      </item>
      
    
      
      <item>
        <title>Default Arguments in C++ Functions</title>
        <description>&lt;p&gt;Function parameters in C++ can have a default argument. If the function is declared, the default argument is specified in the &lt;strong&gt;declaration&lt;/strong&gt; - NOT the function definition.&lt;/p&gt;

&lt;p&gt;If a function declaration contains a parameter with a default argument, all subsequent parameters must also have a default argument supplied.&lt;/p&gt;

&lt;p&gt;If your function is not declared, the default argument can be specified in the function definition.&lt;/p&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// The function declaration contains the default parameter
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The function definition does not contain the default parameter
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;c1&quot;&gt;// If there is no function declaration, the default argument is specified in the function definition:
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Outputs 2 + 10 = 12
&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Outputs 2 + 2 = 4
&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Outputs 2 * 10 = 20
&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Outputs 2 * 2 = 4
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/default_arguments&quot;&gt;Default Arguments: CPP Language reference&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Wed, 18 Jul 2018 20:25:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/07/default-arguments-in-c++-functions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/07/default-arguments-in-c++-functions/</guid>
      </item>
      
    
      
      <item>
        <title>Arrow Operator in C++</title>
        <description>&lt;p&gt;In C++ &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; is the standard member access operator. It has higher precedence than the &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; dereference operator.&lt;/p&gt;

&lt;p&gt;Accessing the member of an object through a pointer requires dereferencing to happen first, so the dereferencing operation must be wrapped in parentheses.&lt;/p&gt;

&lt;h2 id=&quot;example-1-access-member-variable&quot;&gt;Example 1: Access Member Variable&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&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;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mainPerson&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;s&quot;&gt;&quot;Cornelius&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mainPerson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Dereference first, then access member variable:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ID:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ID:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Equivalent:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ID:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Name:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example-2-iterate-over-a-map&quot;&gt;Example 2: Iterate over a Map&lt;/h2&gt;
&lt;p&gt;When you use iterators to loop through a container, you need to dereference the iterator to access each object. The arrow operator can provide a convenient shortcut for this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;David&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;99.9&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;s&quot;&gt;&quot;Elaine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;99.99&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;s&quot;&gt;&quot;Bill&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// Accessing the member requires dereferencing to happen first,
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// hence the placement of parentheses:
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// The arrow operator is shorthand for this, providing member access by an
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// indirect selector. This is equivalent to the line above:
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myMapIt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 18 Jul 2018 13:46:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/07/arrow-operator-in-c++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/07/arrow-operator-in-c++/</guid>
      </item>
      
    
      
      <item>
        <title>HTTP Server in C</title>
        <description>&lt;p&gt;This article describes a simple http server socket in Linux.&lt;/p&gt;

&lt;h2 id=&quot;server-socket&quot;&gt;Server Socket&lt;/h2&gt;
&lt;p&gt;The basic procedure:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Create socket with &lt;code class=&quot;highlighter-rouge&quot;&gt;socket()&lt;/code&gt; call&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bind()&lt;/code&gt; this to an IP and port where it can&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;listen()&lt;/code&gt; for connections, then&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;accept()&lt;/code&gt; connection and &lt;code class=&quot;highlighter-rouge&quot;&gt;send()&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;receive()&lt;/code&gt; data to/from connected sockets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that if &lt;code class=&quot;highlighter-rouge&quot;&gt;struct sockaddr_in serverAddress.sin_addr.s_addr&lt;/code&gt; is set to INADDR_ANY the socket is bound
to all local interfaces. INADDR_ANY is a constant set to zero, defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;netinet/in.h&lt;/code&gt;. This will correspond to an IP address of 0.0.0.0 in the standard IPv4 notation. Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;htonl(INADDR_LOOPBACK)&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;inet_addr(&quot;127.0.0.1&quot;)&lt;/code&gt; are functionally equivalent.&lt;/p&gt;

&lt;h2 id=&quot;simple-example&quot;&gt;Simple Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;netdb.h&amp;gt; // for getnameinfo()
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Usual socket headers
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;arpa/inet.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define SIZE 1024
#define BACKLOG 10  // Passed to listen()
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;report&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr_in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setHttpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;httpHeader&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;c1&quot;&gt;// File object to return
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;htmlData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;index.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;responseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fgets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htmlData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strcat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;responseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&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;c1&quot;&gt;// char httpHeader[8000] = &quot;HTTP/1.1 200 OK\r\n\n&quot;;
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;strcat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;responseData&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;httpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;HTTP/1.1 200 OK&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Socket setup: creates an endpoint for communication, returns a descriptor
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serverSocket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// Domain: specifies protocol family
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;SOCK_STREAM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Type: specifies communication semantics
&lt;/span&gt;        &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;// Protocol: 0 because there is a single protocol for the specified family
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Construct local address structure
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr_in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_family&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sin_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;htonl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INADDR_LOOPBACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//inet_addr(&quot;127.0.0.1&quot;);
&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Bind socket to local address
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// bind() assigns the address specified by serverAddress to the socket
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// referred to by the file descriptor serverSocket.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;serverSocket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                         &lt;span class=&quot;c1&quot;&gt;// file descriptor referring to a socket
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Address to be assigned to the socket
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;// Size (bytes) of the address structure
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Mark socket to listen for incoming connections
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;listening&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverSocket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BACKLOG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;listening&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&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;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error: The server is not listening.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;report&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// Custom report function
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;setHttpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Custom function to set header
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clientSocket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Wait for a connection, create a connected socket if a connection is pending
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&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;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clientSocket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverSocket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clientSocket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;httpHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;httpHeader&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;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clientSocket&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;report&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr_in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hostBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INET6_ADDRSTRLEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serviceBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NI_MAXSERV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// defined in `&amp;lt;netdb.h&amp;gt;`
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;socklen_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getnameinfo&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;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serverAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;addr_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hostBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hostBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;serviceBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serviceBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NI_NUMERICHOST&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;It's not working!!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Server listening on http://%s:%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hostBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serviceBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;protocol-family&quot;&gt;Protocol Family&lt;/h2&gt;
&lt;p&gt;When setting up a socket using &lt;code class=&quot;highlighter-rouge&quot;&gt;socket()&lt;/code&gt; the following protocols are available:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Purpose&lt;/th&gt;
      &lt;th&gt;Man page&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_UNIX&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;AF_LOCAL&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Local communication&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man unix&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_INET&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4 Internet protocols&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man ip&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_INET6&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv6 Internet protocols&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man ipv6&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_IPX&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPX - Novell protocols&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_NETLINK&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Kernel user interface device&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man netlink&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_X25&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;ITU-T X.25 / ISO-8208 protocol&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man x25&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_AX25&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Amateur radio AX.25 protocol&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_ATMPVC&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Access to raw ATM PVCs&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_APPLETALK&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;AppleTalk&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man ddp&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_PACKET&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Low level packet interface&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;man packet&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;AF_ALG&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Interface to kernel crypto API&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;You can acces this list by running &lt;code class=&quot;highlighter-rouge&quot;&gt;man socket&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;socket-type&quot;&gt;Socket Type&lt;/h2&gt;
&lt;p&gt;The socket has the indicated type, which specifies the communication semantics.  Currently defined types are:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_STREAM&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Provides sequenced, reliable, two-way, connection-based byte streams.  An out-of-band data transmission mechanism may be supported. Used for TCP protocol.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_DGRAM&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Supports datagrams - connectionless, unreliable messages of a fixed maximum length. Used for UDP protocol.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_SEQPACKET&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Provides a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length; a consumer is required to read an entire packet with each input system call.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_RAW&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Provides raw network protocol access.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_RDM&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Provides a reliable datagram layer that does not guarantee ordering.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SOCK_PACKET&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Obsolete and should not be used in new programs; see packet(7).&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;constructing-a-local-address-structure&quot;&gt;Constructing a Local Address Structure&lt;/h2&gt;
&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;serverAddress.sin_addr.s_addr&lt;/code&gt; is set to &lt;code class=&quot;highlighter-rouge&quot;&gt;INADDR_ANY&lt;/code&gt; the socket is bound to all local interfaces. &lt;code class=&quot;highlighter-rouge&quot;&gt;INADDR_ANY&lt;/code&gt; is a constant set to zero, defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;netinet/in.h&lt;/code&gt;. This will correspond to an IP address of 0.0.0.0 in the standard IPv4 notation. Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;htonl(INADDR_LOOPBACK)&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;inet_addr(&quot;127.0.0.1&quot;)&lt;/code&gt; are functionally equivalent.&lt;/p&gt;

&lt;h2 id=&quot;bind-socket-to-local-address&quot;&gt;Bind socket to local address&lt;/h2&gt;
&lt;p&gt;When a socket is created with socket(), it exists in a name space (address family) but has no address assigned to it. bind() assigns the address specified by serverAddress to the socket referred to by the file descriptor serverSocket. serverAddressLength specifies the size, in bytes, of the address structure pointed to by serverAddress.&lt;/p&gt;

&lt;p&gt;This operation is known as “assigning a name to a socket”.&lt;/p&gt;

&lt;h2 id=&quot;connecting&quot;&gt;Connecting&lt;/h2&gt;
&lt;p&gt;The programme runs an infinite loop in which we wait and create a connected socket if a connection is pending.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;accept()&lt;/code&gt; function gets the first connection request on the queue of pending connections for the listening socket (in this case denoted by &lt;code class=&quot;highlighter-rouge&quot;&gt;serverSocket&lt;/code&gt;). It then creates a new connected socket and returns a file descriptor referring to this socket. The newly created socket is NOT in a listening state. The original socket (&lt;code class=&quot;highlighter-rouge&quot;&gt;serverSocket&lt;/code&gt;) is unaffected by this call.&lt;/p&gt;

&lt;h2 id=&quot;using-getnameinfo&quot;&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;getnameinfo&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Used in the &lt;code class=&quot;highlighter-rouge&quot;&gt;report()&lt;/code&gt; function&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getnameinfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sockaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// pointer to a generic socket address structure (of type sockaddr_in or sockaddr_in6)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;socklen_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;salen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// size of the above
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;// Caller allocated buffer, will receive host
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;socklen_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hostlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// Size of above
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;// Caller allocate buffer, will receive service name
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;socklen_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;servlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// Size of above
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Getaddrinfo#getnameinfo()&quot;&gt;getaddrinfo/getnameinfo Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 12 Jun 2018 21:26:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/06/http-server-in-c/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/06/http-server-in-c/</guid>
      </item>
      
    
      
      <item>
        <title>List &amp; Dict Comprehensions in Python</title>
        <description>&lt;p&gt;Python comprehensions are &lt;a href=&quot;https://en.wikipedia.org/wiki/Syntactic_sugar&quot;&gt;syntactic sugar&lt;/a&gt; constructs that provide a way to build a list, dictionary or set from a starting list, dictionary or set whilst altering or filtering elements.&lt;/p&gt;

&lt;p&gt;Comprehensions follow mathematical set builder notation rather than map and filter functions.&lt;/p&gt;

&lt;h2 id=&quot;list-comprehension&quot;&gt;List Comprehension&lt;/h2&gt;
&lt;p&gt;Make a List that contains the doubled values of a starting list:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doubled_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubled_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Outputs [4, 8, 12, 16, 20]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You could achieve the same result like this:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doubled_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doubled_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubled_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;…which is considerably more verbose.&lt;/p&gt;

&lt;p&gt;List comprehensions have the same effect as the &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; method in other languages. For example, in JavaScript you could achieve the above like this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doubled_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doubled_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs [ 4, 8, 12, 16, 20 ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;filtering&quot;&gt;Filtering&lt;/h2&gt;
&lt;p&gt;You can filter a list by adding a conditional statement. A filtered list comprehension takes this form:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expression&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expression&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;even_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;odd_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;even_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odd_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Make a list of the cubes of all even numbers&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cubed_even_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;flatten-a-multi-dimensional-list&quot;&gt;Flatten a Multi-Dimensional List&lt;/h2&gt;
&lt;p&gt;To convert a two-dimensional list to a single dimension list, containing all the original elements of the sublists as a single list:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;two_d_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;flattened&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sublist&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_d_list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sublist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flattened&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# prints [1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is known as “flattening” a list.&lt;/p&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;flattened&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;			&lt;span class=&quot;c&quot;&gt;# Item to be appended to flattened&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sublist&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_d_list&lt;/span&gt;	&lt;span class=&quot;c&quot;&gt;# Loop through the list to get the sublists&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sublist&lt;/span&gt;		&lt;span class=&quot;c&quot;&gt;# Loop through each sublist to get the item&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flattened&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# prints [1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note the order:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The item to append to the collection is referenced first&lt;/li&gt;
  &lt;li&gt;Sublists are then generated from the initial 2d list&lt;/li&gt;
  &lt;li&gt;Items are then generated from the sublist&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Syntactic_sugar&quot;&gt;Syntactic Sugar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.datacamp.com/community/tutorials/python-dictionary-comprehension&quot;&gt;Dictionary comprehension tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.pythonforbeginners.com/basics/list-comprehensions-in-python&quot;&gt;List comprehensions tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.u.arizona.edu/~erdmann/mse350/topics/list_comprehensions.html&quot;&gt;Arizona.edu on Comprehensions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.smallsurething.com/list-dict-and-set-comprehensions-by-example/&quot;&gt;Nice tutorial on comprehensions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 27 May 2018 15:04:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/05/list-dict-comprehensions-in-python/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/05/list-dict-comprehensions-in-python/</guid>
      </item>
      
    
      
      <item>
        <title>JavaScript Functions</title>
        <description>&lt;h2 id=&quot;method-invocation-pattern&quot;&gt;Method Invocation Pattern&lt;/h2&gt;
&lt;p&gt;Function defined as an object property - an object &lt;em&gt;method&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&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;na&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;val&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'number'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;val&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;JavaScript binds &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; at execution (late binding), so &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; refers to the &lt;code class=&quot;highlighter-rouge&quot;&gt;myObject&lt;/code&gt; object.&lt;/p&gt;

&lt;h2 id=&quot;function-invocation-pattern&quot;&gt;Function Invocation Pattern&lt;/h2&gt;
&lt;p&gt;Function invocation uses the format &lt;code class=&quot;highlighter-rouge&quot;&gt;functionName()&lt;/code&gt;. In this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; within the function refers to the global object. This can be incredibly confusing. The problem is evident when using an inner function within a method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&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;na&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;c1&quot;&gt;// In the inner function, `this` refers to the global object (e.g. `Window`).&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Intuitively, you'd expect it to refer to the containing object - it does not.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// A workaround is to assign a variable to `this` in the outer function.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// By convention, this variable is named `that`.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;helper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;nx&quot;&gt;that&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;that&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;helper&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;ES6 arrow functions provide a much less hacky solution, since the arrow function &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; is inherited from the containing scope. The above example, rewritten with an arrow function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;value&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;na&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;helper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;helper&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sat, 19 May 2018 20:39:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/05/javascript-functions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/05/javascript-functions/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up An Automatic LetsEncrypt Renewal Cronjob</title>
        <description>&lt;p&gt;This short article outlines how to setup and test a LetsEncrypt auto-renewal cronjob, tested with certbot 0.24.0 on Ubuntu 14.04.&lt;/p&gt;

&lt;p&gt;Depending on your version of Certbot/Letsencrypt, auto-renewal may be built in&lt;/p&gt;

&lt;h2 id=&quot;final-command&quot;&gt;Final Command&lt;/h2&gt;
&lt;p&gt;This cronjob runs at a random second between 02:00 and 03:00 every day:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;00 02 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/bin/perl -e &lt;span class=&quot;s1&quot;&gt;'sleep int(rand(3600))'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /opt/certbot-auto renew &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /etc/init.d/apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This command specifies a pause of between 0-3599 seconds, followed by the certbot renewal. If renewal is successful, an Apache restart is triggered.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Better Command - the above command restarts Apache whether or not the certificate has renewed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Final: run at a random second between 02:00 and 03:00 every day&lt;/span&gt;
00 02 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/bin/perl -e &lt;span class=&quot;s1&quot;&gt;'sleep int(rand(3600))'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /opt/certbot-auto renew&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, the Apache restart is not triggered - the restart is unecessary, since the new cert is symlinked in the Apache site config file.&lt;/p&gt;

&lt;h2 id=&quot;quiet-mode&quot;&gt;Quiet Mode&lt;/h2&gt;
&lt;p&gt;Once you’ve verified that the cammand as working as expected, it’s a good idea to have it run in quiet mode. This suppresses all output apart from error messages, which will help clean up your email inbox.&lt;/p&gt;

&lt;h2 id=&quot;test&quot;&gt;Test&lt;/h2&gt;
&lt;p&gt;Check certificate expiry time to verify that renewal has worked:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Check expiry of cert: replace example.com&lt;/span&gt;
sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/cert.pem
&lt;span class=&quot;nv&quot;&gt;notBefore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;May  8 07:34:22 2018 GMT
&lt;span class=&quot;nv&quot;&gt;notAfter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Aug  6 07:34:22 2018 GMT&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set up a test cronjob - this will be the same as the actual script except:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It will trigger at a random second within the specified time&lt;/li&gt;
  &lt;li&gt;It will force a certificate renewal&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open crontab for editing&lt;/span&gt;
sudo crontab -e

&lt;span class=&quot;c&quot;&gt;# Test: force certificate renewal at 10:26 on a random second&lt;/span&gt;
26 10 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/bin/perl -e &lt;span class=&quot;s1&quot;&gt;'sleep int(rand(60))'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /opt/certbot-auto renew --force-renew &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /etc/init.d/apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check that the certifcate expiry time has updated by re-running &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/cert.pem&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check that Apache has reloaded:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat /var/log/apache2/error.log | grep SIGTERM&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check the LetsEncrypt renewal log:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;su
cat /var/log/letsencrypt/letsencrypt.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You should also receive a status report email from cron.&lt;/p&gt;

&lt;p&gt;Don’t forget to replace the test command with the actual command.&lt;/p&gt;
</description>
        <pubDate>Tue, 08 May 2018 15:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/05/set-up-an-automatic-letsencrypt-renewal-cronjob/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/05/set-up-an-automatic-letsencrypt-renewal-cronjob/</guid>
      </item>
      
    
      
      <item>
        <title>Passing Data Between Vue Components</title>
        <description>&lt;p&gt;Components are re-usable Vue instances that better allow you to keep code separated and modular. They are very flexible - child components can be defined and used within parents. This can be a really useful way of preventing repetitive markup.&lt;/p&gt;

&lt;p&gt;Single-file components take things to the next level. These keep all component data within a single &lt;code class=&quot;highlighter-rouge&quot;&gt;.vue&lt;/code&gt; file - comprised of a HTML like structure with &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;template&amp;gt;&lt;/code&gt; (markup), &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;script&amp;gt;&lt;/code&gt; (JavaScript) and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;style&amp;gt;&lt;/code&gt; (CSS) components. This can be really useful for larger projects or projects in which the entire frontend is built in JavaScript.&lt;/p&gt;

&lt;p&gt;If you use &lt;code class=&quot;highlighter-rouge&quot;&gt;vue-cli&lt;/code&gt; to spin up a Vue/Webpack project, the project comes with single-file components pre-installed.&lt;/p&gt;

&lt;p&gt;This article outlines how to pass data between components in the context of single file components.&lt;/p&gt;

&lt;h2 id=&quot;passing-data-from-parent-component-to-child-component&quot;&gt;Passing Data From Parent Component to Child Component&lt;/h2&gt;
&lt;h3 id=&quot;import-child-in-parent-component&quot;&gt;Import Child in Parent Component&lt;/h3&gt;
&lt;p&gt;Import the child component so that it can be used in the parent, and declare the component in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;script&amp;gt;&lt;/code&gt; section:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// @ is an alias to /src (in a vue-cli generated project)&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'@/components/Child.vue'&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// You also need to declare that the imported child component will be used:&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;components&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;nx&quot;&gt;Child&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;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;invoke-the-child-component-in-the-parent&quot;&gt;Invoke the Child Component in the Parent&lt;/h3&gt;
&lt;p&gt;Within the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;template&amp;gt;&lt;/code&gt; section of the parent component, call the child component. Prop data is passed as an attribute.&lt;/p&gt;

&lt;p&gt;You can pass data inline, or define it within the &lt;code class=&quot;highlighter-rouge&quot;&gt;data()&lt;/code&gt; method of the component.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- simplest prop - pass a string --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Child&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;This is my title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/Child&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Pass an object, defined inline --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Child&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;:parentData=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{msg: 'xxx'}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/Child&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Pass an object, defined in the `data()` method --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Child&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;:parentData=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myData&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/Child&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Pass a string variable, defined in `data()`. Note colon. --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Child&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;:stringProp=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;stringMessage&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/Child&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that prepending a colon to the prop attribute indicates that a variable is passed, not a string.&lt;/p&gt;

&lt;h3 id=&quot;receiving-the-prop-data-in-the-child&quot;&gt;Receiving the Prop Data in the Child&lt;/h3&gt;
&lt;p&gt;You must declare the prop in the child component &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;script&amp;gt;&lt;/code&gt; section - you can then use it as a normal Vue-defined variable:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Child'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// To use props, they must be declared&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;props&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;na&quot;&gt;parentData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;stringProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&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;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;pass-data-from-child-to-parent&quot;&gt;Pass Data from Child to Parent&lt;/h2&gt;
&lt;p&gt;You can send data from a child to a parent component by means of Vue’s built-in &lt;code class=&quot;highlighter-rouge&quot;&gt;$emit()&lt;/code&gt; method. The first parameter of &lt;code class=&quot;highlighter-rouge&quot;&gt;$emit&lt;/code&gt; is the event that should be listened for in the parent component. The second (optional) parameter is the data value to pass.&lt;/p&gt;

&lt;p&gt;Parent:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Parent.vue --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!--
    Listen for `childToParent`: the first parameter of the `$emit` method
    in the child component. We're also listening and reacting to an
    `increment` event - in this case, we increment a counter inline.
    --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Child&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;:parentData=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myData&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-on:childToParent=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;onChildClick&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-on:increment=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;counter++&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/PassProps&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'@/components/Child.vue'&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;data&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;counter&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;na&quot;&gt;fromChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// This value is set to the value emitted by the child&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;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'about'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;components&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;nx&quot;&gt;Child&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;methods&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;c1&quot;&gt;// Triggered when `childToParent` event is emitted by the child.&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;onChildClick&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fromChild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this example, the parent listens for the &lt;code class=&quot;highlighter-rouge&quot;&gt;childToParent&lt;/code&gt; event (defined by the &lt;code class=&quot;highlighter-rouge&quot;&gt;$emit&lt;/code&gt; method) and triggers the &lt;code class=&quot;highlighter-rouge&quot;&gt;onChildClick()&lt;/code&gt; method when the event is received. This method in turn sets the &lt;code class=&quot;highlighter-rouge&quot;&gt;fromChild&lt;/code&gt; variable. It also emits an &lt;code class=&quot;highlighter-rouge&quot;&gt;increment&lt;/code&gt; event in a simpler way when the button is clicked, by placing &lt;code class=&quot;highlighter-rouge&quot;&gt;$emit&lt;/code&gt; inline in the template.&lt;/p&gt;

&lt;p&gt;In the child component:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Child.vue --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;child&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Simplest - call `$emit()` inline--&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-on:click=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$emit('increment')&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Click me to increment!&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- set a variable then trigger a method which calls `$emit()` --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;for=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;child-input&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Child input: &lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;child-input&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;msg&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-model=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;childMessage&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-on:keyup=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;emitToParent&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;data&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;childMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&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;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Child'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;methods&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;c1&quot;&gt;// Define the method that emits data to the parent as the first parameter to `$emit()`.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// This is referenced in the &amp;lt;template&amp;gt; call in the parent. The second parameter is the payload.&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;emitToParent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$emit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'childToParent'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;childMessage&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This example emits a user-entered string back to the parent component.&lt;/p&gt;
</description>
        <pubDate>Wed, 02 May 2018 11:48:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/05/passing-data-between-vue-components/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/05/passing-data-between-vue-components/</guid>
      </item>
      
    
      
      <item>
        <title>Persistent Banning of IP Addresses with Fail2Ban </title>
        <description>&lt;p&gt;If you’re using Fail2Ban you can easily set up a list of banned IP addresses that Fail2Ban will use to set up &lt;code class=&quot;highlighter-rouge&quot;&gt;DROP&lt;/code&gt; rules in iptables whenever Fail2Ban starts. This is very useful since it is easy to persist IP bans across reboots.&lt;/p&gt;

&lt;p&gt;You need to modify the relevant action config file, and reference a “blocklist” file. When you add IP addresses to the blocklist and reload Fail2Ban, the relevant drop rules will be added.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Action files specify which commands are executed to ban and unban an IP address. Like with jail.conf files, if you desire local changes create an &lt;code class=&quot;highlighter-rouge&quot;&gt;[actionname].local&lt;/code&gt; file in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/action.d&lt;/code&gt; directory and override the required settings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Action files have two sections, [Definition] and [Init]. The [Init] section enables action-specific settings. These can be overridden for a particular jail (in &lt;code class=&quot;highlighter-rouge&quot;&gt;jail.local&lt;/code&gt;) as options of the action’s specification in that jail.&lt;/p&gt;

&lt;h2 id=&quot;ip-blocklist-and-associated-action&quot;&gt;IP Blocklist and Associated Action&lt;/h2&gt;
&lt;p&gt;For our purposes, we will amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;actionstart&lt;/code&gt; command in the &lt;code class=&quot;highlighter-rouge&quot;&gt;[Definition]&lt;/code&gt; section. This command (or commands) executes when the jail starts. To override the default action, create a corresponding &lt;code class=&quot;highlighter-rouge&quot;&gt;.local&lt;/code&gt; file and add the amended &lt;code class=&quot;highlighter-rouge&quot;&gt;actionstart&lt;/code&gt; command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;sudo nano /etc/fail2ban/action.d/iptables-multiport.local

&lt;span class=&quot;c&quot;&gt;# Enter the following to override the default actionstart command:&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Add drop rules for specified IPs.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Enter IPs to permanently ban, one per line in /etc/fail2ban/ip.blocklist:&lt;/span&gt;
actionstart &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &amp;lt;iptables&amp;gt; -N f2b-&amp;lt;name&amp;gt;
              &amp;lt;iptables&amp;gt; -A f2b-&amp;lt;name&amp;gt; -j &amp;lt;returntype&amp;gt;
              &amp;lt;iptables&amp;gt; -I &amp;lt;chain&amp;gt; -p &amp;lt;protocol&amp;gt; -m multiport --dports &amp;lt;port&amp;gt; -j f2b-&amp;lt;name&amp;gt;
              cat /etc/fail2ban/ip.blocklist | &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;IP; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;iptables -I f2b-&amp;lt;name&amp;gt; 1 -s &lt;span class=&quot;nv&quot;&gt;$IP&lt;/span&gt; -j DROP; &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After creating and editing the file, save and exit (ctrl-o followed by ctrl-x).&lt;/p&gt;

&lt;p&gt;Create a file &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/ip.blocklist&lt;/code&gt; and enter IP addresses to ban - one per line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restart Fail2Ban for the changes to be applied&lt;/strong&gt;. If you run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo iptables -S&lt;/code&gt; now, you should see rules like &lt;code class=&quot;highlighter-rouge&quot;&gt;-A f2b-ssh -s 11.22.333.444/32 -j DROP&lt;/code&gt; associated with your different jails.&lt;/p&gt;

&lt;h2 id=&quot;auto-add-ip-addresses-to-the-blocklist&quot;&gt;Auto Add IP Addresses to the Blocklist&lt;/h2&gt;
&lt;p&gt;If you want to automatically add IPs to your list as they are banned, you need to amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;actionban&lt;/code&gt; command such that the IP is appended to your list when the IP is banned:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;actionban &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &amp;lt;iptables&amp;gt; -I f2b-&amp;lt;name&amp;gt; 1 -s &amp;lt;ip&amp;gt; -j &amp;lt;blocktype&amp;gt;
            &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &amp;lt;ip&amp;gt; &amp;gt;&amp;gt; /etc/fail2ban/ip.blocklist&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Commands specified in the [Definition] section of are executed through a system shell so shell redirection and process control is allowed. Note that commands should return 0, or an error will be logged (ref: &lt;code class=&quot;highlighter-rouge&quot;&gt;man jail.conf&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://zach.seifts.us/posts/2013/07/14/how-make-fail2ban-bans-persistent&quot;&gt;Make Fail2Ban bans persistent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 26 Apr 2018 09:05:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/04/persistent-banning-of-ip-addresses-with-fail2ban/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/04/persistent-banning-of-ip-addresses-with-fail2ban/</guid>
      </item>
      
    
      
      <item>
        <title>Amend Bitcoin-Qt Persistent Settings for Bitcoin Core</title>
        <description>&lt;p&gt;When you first run the Bitcoin core wallet, you will be given an opportunity to customise the location of the default data directory (which in Linux is &lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/.bitcoin&lt;/code&gt;). If you need to change the data directory after the first launch, there is no option to do so from within the GUI. Many Stack Overflow answers suggest launching &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt; with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-datadir&lt;/code&gt; option - e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt -datadir=/path/to/custom/datadir&lt;/code&gt; - this works, however you can easily amend the QT configuration so that the proper data directory is referenced by default.&lt;/p&gt;

&lt;h2 id=&quot;qsettings-for-bitcoin&quot;&gt;QSettings for Bitcoin&lt;/h2&gt;
&lt;p&gt;The Bitcoin Core GUI wallet is based on QT, and it uses &lt;code class=&quot;highlighter-rouge&quot;&gt;QSettings&lt;/code&gt; to store settings.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Users normally expect an application to remember its settings (window sizes and positions, options, etc.) across sessions. This information is often stored in the system registry on Windows, and in XML preferences files on Mac OS X. On Unix systems, in the absence of a standard, many applications (including the KDE applications) use INI text files.
&lt;a href=&quot;https://doc.qt.io/archives/qt-4.8/qsettings.html#details&quot;&gt;QSettings documentation&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;location-of-config-file-linux&quot;&gt;Location of Config File: Linux&lt;/h3&gt;
&lt;p&gt;On Linux/Unix systems, the following files are used by default:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/.config/Bitcoin/Bitcoin-Qt.conf&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/.config/Bitcoin-Qt.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For myself, running Bitcoin Core under Ubuntu 16.04 the config file is &lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/.config/Bitcoin/Bitcoin-Qt.conf&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;location-of-config-file-mac-os&quot;&gt;Location of Config File: Mac OS&lt;/h3&gt;
&lt;p&gt;On Mac OS X check the following locations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/Library/Preferences/com.Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$HOME/Library/Preferences/com.Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/Library/Preferences/com.Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/Library/Preferences/com.Bitcoin&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;location-of-config-file-windows&quot;&gt;Location of Config File: Windows&lt;/h3&gt;
&lt;p&gt;On Windows, check the following registry paths:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HKEY_CURRENT_USER\Software\Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HKEY_CURRENT_USER\Software\Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HKEY_LOCAL_MACHINE\Software\Bitcoin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HKEY_LOCAL_MACHINE\Software\Bitcoin&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don’t run MacOS or Windows so I haven’t checked these locations - this info is based on that provided in the QT QSettings documentation.&lt;/p&gt;

&lt;h2 id=&quot;edit-the-config&quot;&gt;Edit the Config&lt;/h2&gt;
&lt;p&gt;Once you’ve located the config file, you can edit it like any other text file, and you’ll be able to amend the data directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Make a backup just in case&lt;/span&gt;
cp &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.config/Bitcoin/Bitcoin-Qt.conf &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.config/Bitcoin/Bitcoin-Qt.conf.bak

&lt;span class=&quot;c&quot;&gt;# Edit the file&lt;/span&gt;
vim &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.config/Bitcoin/Bitcoin-Qt.conf

&lt;span class=&quot;c&quot;&gt;# Save and exit&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The data directory key is &lt;code class=&quot;highlighter-rouge&quot;&gt;stdDataDir&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;General]
...
&lt;span class=&quot;nv&quot;&gt;strDataDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/media/secure-hdd-2/bitcoin-data
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just amend this value to reference your data directory.&lt;/p&gt;

&lt;p&gt;You can now launch &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt; as normal without specifying the custom data directory.&lt;/p&gt;

&lt;h2 id=&quot;a-note-on-moving-data-directories&quot;&gt;A Note on Moving Data Directories&lt;/h2&gt;
&lt;p&gt;Don’t open Bitcoin Core in a different data directory without first copying across all data from the original data directory (e.g. using &lt;code class=&quot;highlighter-rouge&quot;&gt;rsync&lt;/code&gt;). Otherwise, blocks will need to be re-indexed - which is a lengthy process, and unecessary if you already have an up-to-date installation.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://doc.qt.io/archives/qt-4.8/qsettings.html#details&quot;&gt;QSetttings documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 10 Apr 2018 19:58:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/04/amend-bitcoin-qt-persistent-settings-for-bitcoin-core/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/04/amend-bitcoin-qt-persistent-settings-for-bitcoin-core/</guid>
      </item>
      
    
      
      <item>
        <title>Combine Vectors in C++</title>
        <description>&lt;p&gt;Build a combined vector from two input vectors.&lt;/p&gt;

&lt;p&gt;There are a number of ways to achieve this - the function below outlines some options:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * Accept two vectors of strings as input parameters.
 * Pass these in by reference for efficiency, and as `const` to protect the originals.
 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vcat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&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;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Option 1: insert()
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Option 2: C++ 11 range-based for-loop
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Option 3: Loop through the extra collection using an iterator
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;const_iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&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;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 04 Apr 2018 14:30:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/04/combine-vectors-in-c-plus-plus/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/04/combine-vectors-in-c-plus-plus/</guid>
      </item>
      
    
      
      <item>
        <title>Javascript Resources</title>
        <description>&lt;p&gt;Collection of resources for learning Javascript.&lt;/p&gt;

&lt;h2 id=&quot;node&quot;&gt;Node&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://nodeschool.io&quot;&gt;nodeschool.io&lt;/a&gt;:
    &lt;ul&gt;
      &lt;li&gt;Learn javascripting basics &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install -g javascripting&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Learn Node basics: &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install -g learnyounode&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Learn git: &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install -g git-it&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/nodejs/getting-started/blob/master/README.md&quot;&gt;Get started with Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;online-javascript-courses--and-cheatsheets&quot;&gt;Online Javascript Courses  and Cheatsheets&lt;/h2&gt;
&lt;p&gt;Useful cheat sheet from WebsiteSetup:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://websitesetup.org/javascript-cheat-sheet/&quot;&gt;JavaScript Cheat Sheet&lt;/a&gt;: article with downloadable PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Udacity has loads of free JavaScript courses. I did the Design Patterns course, which was very useful:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://eu.udacity.com/course/javascript-design-patterns--ud989&quot;&gt;Udacity: JavaScript Design Patterns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.codecademy.com/tracks/javascript&quot;&gt;Code Academy: Javascript&lt;/a&gt; online interactive course.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs101/&quot;&gt;Introduction to Computing Principles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.lynda.com/Node-js-tutorials/Learning-Node-js/612195-2.html&quot;&gt;Lynda: Learning Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;general-javascript-books--ebooks&quot;&gt;General Javascript Books &amp;amp; eBooks&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://eloquentjavascript.net&quot;&gt;Eloquent Javascript&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide&quot;&gt;JavaScript Guide&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://bonsaiden.github.io/JavaScript-Garden/&quot;&gt;JavaScript Garden&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gitbook.com/book/gitbookio/javascript/details&quot;&gt;Learn Javascript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;btc-related-javascript&quot;&gt;BTC Related JavaScript&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bip32/bip32.github.io&quot;&gt;Bip32 Generator&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;git clone https://github.com/bip32/bip32.github.io.git ; cd bip32.github.io ; open index.html&lt;/code&gt; - Bip32 Deterministic Heirarchical Keys (prefix xpub* and xprv*) based on a simple brainwallet (aka arbitrary mnemonic) passphrase.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/dcpos/bip39&quot;&gt;Bip39 Mnemonic Code Converter&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install bip39 ; npm run compile&lt;/code&gt; lets you create Bip39 mnemonics (typically 12 words) used for deterministic keys, typically for Bip32.&lt;/li&gt;
&lt;/ul&gt;

&lt;!-- ## Bitcore.js --&gt;
&lt;p&gt;&amp;lt;!– * &lt;a href=&quot;https://www.youtube.com/watch?v=TmkN8yYyOv8&quot;&gt;Bitcoin 101 - Getting Started With Bitcore - A Full JavaScript Implementation of Bitcoin&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;https://github.com/wobine/blackboard101/blob/master/BitcoreDayOne.html&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/chulini/bitcoin-quick-tools&quot;&gt;Bitcoin Quick Tools&lt;/a&gt; - Simple browser-based app (loaded locally) that is Bitcore.js. Has key and address generator and simple transaction tool. Useful working example of browserfy bitcore.js code. –&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 01 Apr 2018 10:26:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/04/javascript-resources/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/04/javascript-resources/</guid>
      </item>
      
    
      
      <item>
        <title>Function Pointers in C++</title>
        <description>&lt;p&gt;In C++ like many other languages, functions can be assigned to variables. Functions can be passed into other functions as parameters.&lt;/p&gt;

&lt;h2 id=&quot;full-example&quot;&gt;Full Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Define std::vector type for brevity
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Declare functions
// ---------------------------------------------------------------------------------------------------------------------
// This function receives the function pointer as third parameter
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combineVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// These functions will be assigned to function pointers:
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xorInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;1&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;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&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;mi&quot;&gt;1&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;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Set up function pointers
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Declare a function pointer variable.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Defines a symbol xorEls, pointer to a function that takes two ints as arguments and returns an int
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xorEls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Set it with the address of a function (the use of '&amp;amp;' is optional).
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;xorEls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xorInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Pass the function pointer for use in another function
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Function pointer is the third function argument.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xored&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combineVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xorEls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xored&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Output result
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Repeat with a different function to demonstrate the point of function pointers
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Output a new vector which holds the product of each element in two input vectors.
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiplyEls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;multiplyEls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiplied&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combineVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiplyEls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiplied&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Function definitions
// ---------------------------------------------------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * Combine two integer vectors - operate on elements of input vectors in place
 * by means of a provided function, creating a new vector. Performs the operation
 * up to the length of the shortest provided vector.
 * @param  vec1 std::vector&amp;lt;int&amp;gt;
 * @param  vec2 std::vector&amp;lt;int&amp;gt;
 * @param  func A function pointer
 * @return zipped A std::vector&amp;lt;int&amp;gt; object with each element operated on in-place.
 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;combineVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size_type&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;containerSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;containerSize&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec1Size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;containerSize&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2Size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;containerSize&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zipLen&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vec1Size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2Size&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec1Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zipLen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// Append the result of the passed-in function to `combined`
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;combined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vec1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combined&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xorInts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cprogramming.com/tutorial/typedef.html&quot;&gt;Function Pointers Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 29 Mar 2018 09:10:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/03/function-pointers-in-c++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/03/function-pointers-in-c++/</guid>
      </item>
      
    
      
      <item>
        <title>Parse Command Line Arguments in  C and C++</title>
        <description>&lt;p&gt;Command line arguments are available by adding two parameters.&lt;/p&gt;

&lt;p&gt;Run Programme: &lt;code class=&quot;highlighter-rouge&quot;&gt;./prog -a -b -cde&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This passes four arguments to the programme:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;./prog&lt;/li&gt;
  &lt;li&gt;-a&lt;/li&gt;
  &lt;li&gt;-b&lt;/li&gt;
  &lt;li&gt;-cde&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This data is available within &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; as the second input parameter (by convention, &lt;code class=&quot;highlighter-rouge&quot;&gt;argv[]&lt;/code&gt;). The first input parameter to main holds the number of passed arguments (in this case, four) and by convention is called argc.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;argv[]&lt;/code&gt; parameter is a C-style array of primitive strings (&lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; objects)- and may be represented as &lt;code class=&quot;highlighter-rouge&quot;&gt;char * argv[]&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;char ** argv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;main(argc, char ** argv)&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;main(argc, char * argv[])&lt;/code&gt; are equivalent:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;char ** argv&lt;/code&gt;: declare &lt;code class=&quot;highlighter-rouge&quot;&gt;argv&lt;/code&gt; as pointer to pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt; (A pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;char * argv[]&lt;/code&gt;: declare argv as array of pointer to char (A primitive array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; objects)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are equivalent because a pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt; is the same as an array of &lt;code class=&quot;highlighter-rouge&quot;&gt;char *&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the current example, &lt;code class=&quot;highlighter-rouge&quot;&gt;argc&lt;/code&gt; is 4 and the four elements of &lt;code class=&quot;highlighter-rouge&quot;&gt;argv&lt;/code&gt; are pointers to the arrays of characters passed in as arguments.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;          +---+         +---+---+---+---+---+---+---+
argv ----&amp;gt;| 0 |--------&amp;gt;| . | / | p | r | o | g | \0|
          +---+         +---+---+---+---+---+---+---+
          | 1 |--------&amp;gt;| - | a | \0|
          +---+         +---+---+---+
          | 2 |--------&amp;gt;| - | b | \0|
          +---+         +---+---+---+---+---+
          | 3 |--------&amp;gt;| - | c | d | e | \0|
          +---+         +---+---+---+---+---+
          | 4 |--------&amp;gt; NULL
          +---+&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;parse-command-line-arguments-demo&quot;&gt;Parse Command Line Arguments: Demo&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * Demo of parsing command-line argument array.
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&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;c1&quot;&gt;// Extract arguments from argument array.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Because of the parentheses, argv (a pointer) is incremented first, then
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// dereferenced. The loop conditional is also dependent on the first element
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// of the new pointed-to element being the char '-', which denotes the start
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// of an option. Note that argv is incremented first, which excludes the first
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// element (the command).
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&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;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sc&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;c1&quot;&gt;// Set appropriate actions
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// Walk down the string (char array) pointed to by the current argv[0]
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// pointer. The expression `*++(argv[0])` increments argv[0] and provides
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// a pointer to the first non '-' character. Dereferences the pointer to
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// provide the value. Loops to the end of the end of the char array, so
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// multiple options can be read (i.e. `command -abc`).
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// `while(c = *++argv[0])` is the same as `while((c = *++argv[0]) != 0)`
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&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;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Set flag a&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Set flag b&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Set flag c&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'d'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Set flag d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'e'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Set flag e&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'h'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Provide some help!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nl&quot;&gt;default:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Option &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; is unknown.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;usage: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &amp;lt;-abcde -h&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&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;p&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 27 Mar 2018 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2018/03/parse-command-line-arguments-in-c/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/03/parse-command-line-arguments-in-c/</guid>
      </item>
      
    
      
      <item>
        <title>C++ Pointers</title>
        <description>&lt;p&gt;In C++, a pointer is an object whose value is the memory address of another object. In other words, a pointer is a variable which stored the memory address of another variable.&lt;/p&gt;

&lt;p&gt;A pointer references a location in memory. When declaring a pointer, the type of the pointed-to variable must be specified:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Declare xPtr as a pointer to an int x, referenced by the address of x.
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Declare yPtr as a pointer to a double y, referenced by the address of y.
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Specifying type when declaring a pointer is necessary because when the pointer is dereferenced (i.e. the pointed-to value is accessed) the type needs to be known.&lt;/p&gt;

&lt;h2 id=&quot;dereferencing&quot;&gt;Dereferencing&lt;/h2&gt;
&lt;p&gt;To access the value held in the memory address held by a pointer, the pointer is &lt;strong&gt;dereferenced&lt;/strong&gt; using the &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; operator - the same operator used to declare a pointer variable:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// assign a value to integer variable x
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Assign the address of x to integer pointer ptr
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Output the pointed-at value - in this case, 5;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;pointer-access&quot;&gt;Pointer Access&lt;/h2&gt;
&lt;p&gt;For:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…the following holds:&lt;/p&gt;

&lt;table class=&quot;table-bordered&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Variable&lt;/th&gt;
      &lt;th&gt;Output&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Returns the address that &lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt; points to: 0x7fff829afe04&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;ptr&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Returns the pointer’s own address, the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt;: 0x7fff829afe08&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*ptr&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Dereference the pointer &lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt; - return the value held at the address held (pointed-to) by &lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt;: 5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;x&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Return the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt;: 0x7fff829afe04&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*&amp;amp;ptr&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Dereference the address of ptr - return the value held in the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;ptr&lt;/code&gt;: 0x7fff829afe04&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;*&amp;amp;x&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Dereference the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt;, returns the value held in the address of &lt;code class=&quot;highlighter-rouge&quot;&gt;x&lt;/code&gt;: 5&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;pointer-to-pointer&quot;&gt;Pointer to Pointer&lt;/h2&gt;
&lt;p&gt;Pointers generally contain the memory address of a variable - but they can also contain the address of another pointer.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Pointer to num
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;numPtrPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numPtr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Pointer to pointer
&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Value of num : &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs 10
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Dereference numPtr: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs 10
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Dereference numPtrPtr: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numPtrPtr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Outputs 10
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Using a pointer-to-pointer as a function parameter makes it possible to modify values within a function with those values persisting outside the function.&lt;/p&gt;

&lt;p&gt;It is not likely that you need to use pointer-to-pointer type structures in modern C++ code. References are available for passing to a function by reference rather than value, and rather than pointing to an array of strings, it’s probably better to use &lt;code class=&quot;highlighter-rouge&quot;&gt;std::vector&amp;lt;std::string&amp;gt;&lt;/code&gt;. However, the &lt;code class=&quot;highlighter-rouge&quot;&gt;char **&lt;/code&gt; notation does pop up - I recently saw this while researching the C &lt;code class=&quot;highlighter-rouge&quot;&gt;getopt()&lt;/code&gt; function - in which an &lt;a href=&quot;https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html&quot;&gt;example&lt;/a&gt; showed arguments to the &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function are presented as &lt;code class=&quot;highlighter-rouge&quot;&gt;char **argv&lt;/code&gt;, rather than the more common char &lt;code class=&quot;highlighter-rouge&quot;&gt;char *argv[]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;pointer-to-pointerpointer-to-char--array-equivalence&quot;&gt;Pointer to Pointer/Pointer to char * array Equivalence&lt;/h2&gt;
&lt;p&gt;A sequence of strings can be passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; as an argument, if the main function is able to receive them.&lt;/p&gt;

&lt;p&gt;You give &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; the capacity to receive arguments by adding two parameters to the function - an &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt; and a pointer to &lt;code class=&quot;highlighter-rouge&quot;&gt;char&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following are equivalent:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * Declare argv as array of pointer to char
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&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;c1&quot;&gt;// Loop through parameters
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;argv[&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;]: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * Declare argv as pointer to pointer to char
 * This declaration is valid - as far as I can tell, it is less common in C++.
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;c1&quot;&gt;// Access arguments in the same way as above.
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Because &lt;code class=&quot;highlighter-rouge&quot;&gt;char *argv[]&lt;/code&gt; is read ‘declare argv as array of pointer to char’, and the array argument is demoted to a pointer to the first element in that array, &lt;code class=&quot;highlighter-rouge&quot;&gt;char *argv[]&lt;/code&gt; is equivalent to &lt;code class=&quot;highlighter-rouge&quot;&gt;char **argv&lt;/code&gt; - which is read as: ‘declare argv as pointer to pointer to char’&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/doc/tutorial/pointers/&quot;&gt;Pointers tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.codeproject.com/articles/4894/pointer-to-pointer-and-reference-to-pointer&quot;&gt;Pointer to Pointer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html&quot;&gt;Extensive Tutorial on Pointers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.learncpp.com/cpp-tutorial/6-14-pointers-to-pointers/&quot;&gt;Pointers to Pointers &amp;amp; Multidimensional Arrays&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://isocpp.org/faq&quot;&gt;C++ Super FAQ&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cdecl.org/&quot;&gt;C++ Translator!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 22 Mar 2018 21:24:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2018/03/c-plus-plus-pointers/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/03/c-plus-plus-pointers/</guid>
      </item>
      
    
      
      <item>
        <title>Introduction to Vectors in C++</title>
        <description>&lt;p&gt;C-style arrays in C and C++ are not dynamic - the compiler needs to know the size of the array (the type and number of elements) in order to properly allocate memory. This is quite different to &lt;a href=&quot;https://en.wikipedia.org/wiki/Interpreted_language&quot;&gt;interpreted languages&lt;/a&gt; like Python, PHP and JavaScript, where arrays are inherently dynamic - you don’t need to specify data type and size in advance.&lt;/p&gt;

&lt;p&gt;Vectors in C++ are standard containers which provide powerful dynamic-array like functionality, with fixed-time access to elements in any order. Vectors are defined by a template class available in the &lt;a href=&quot;https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library&quot;&gt;standard library&lt;/a&gt; - you just need to add &lt;code class=&quot;highlighter-rouge&quot;&gt;#include &amp;lt;vector&amp;gt;&lt;/code&gt; to your header file to have access to vector functionality.&lt;/p&gt;

&lt;p&gt;A C++ vector can be described as a dynamic C-style array - with fast and efficient access to individual elements in any order. You don’t need to worry about memory and size allocation.  Subscripting (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;myVector[]&lt;/code&gt;) access is provided as with C-style arrays.&lt;/p&gt;

&lt;p&gt;Vectors work by setting up an initial memory allocation for your data. If more data is added and the allocation is exceeded, the vector class creates a new, bigger array in memory. The old array is copied across to the new, before being deleted. This is all abstracted away so you don’t need to worry about it, though you should probably take measures to minimise re-allocation - which will help maximise performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article is an ongoing summary of my notes on functions in C++. Please don’t assume that what you read here is accurate. For a more complete description of vectors in C++, check the references presented below.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;declaration&quot;&gt;Declaration&lt;/h2&gt;
&lt;p&gt;Include the appropiate header to give access to the vector class. Then declare the vector - which shoudl specify the data type that will be contained by the vector:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;vector&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Define a vector that will contain integers
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myIntsContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Define a vector that will contain doubles
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myDoublesContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;For convenience, you can use a &lt;code class=&quot;highlighter-rouge&quot;&gt;typedef&lt;/code&gt; statement to make declarations more concise:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Set up aliases
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doubleVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Declarations
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myIntsContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doubleVec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myDoublesContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;initialising&quot;&gt;Initialising&lt;/h2&gt;
&lt;p&gt;To initialise, you can use an initialiser list provided your compiler supports this. This method works with g++ version 5.4.0 on Ununtu, compiling with the &lt;code class=&quot;highlighter-rouge&quot;&gt;c++11&lt;/code&gt; flag.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Method 1
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&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;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Method 2 (equivalent to method 1)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myAltVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can also specify the initial size during the declaration, and only set values later:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Specify size in the vector constructor.
// This works with int data type, but will cause problems with aggregate data types.
// See the std::vector::reserve() method
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// You can still dynamically add elements, even though the size was specified during initialisation
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// myVec is now {7,8,9,10}
&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.cplusplus.com/reference/vector/vector/reserve/&quot;&gt;reserve() method&lt;/a&gt; is a better option for specifying an original size rather than using the vector constructor, which will cause problems when the vector holds aggregate data:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyVal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyVal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Set the capacity for this vector
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Add initial data
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&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;s&quot;&gt;&quot;Option 1&quot;&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Option 2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;s&quot;&gt;&quot;Option 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&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;c1&quot;&gt;// Up to 7 more elements can be added with re-allocation
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Option 4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyVal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Initialising With Values
————————
To initialise a vector with 5 elements, each element being the &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt; 42:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// v is {42, 42, 42, 42, 42}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the first parameter is the number of elements, and the second parameter is the value to which they should be set.&lt;/p&gt;

&lt;p&gt;Be careful to distinguish between this method and curly-brace initialisers:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// v is {5, 42}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Curly brace initialisation treats each element in the intialisation list as an element, and constructs the vector accordingly.&lt;/p&gt;

&lt;h2 id=&quot;adding-elements&quot;&gt;Adding Elements&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;vector.assign(n, el)&lt;/code&gt; method overwrites the vector, such that it contains &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; elements, each defined by &lt;code class=&quot;highlighter-rouge&quot;&gt;el&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;vector.push_back(el)&lt;/code&gt; method appends an element to the vector.&lt;/p&gt;

&lt;p&gt;To add an element to a position specified by an iterator use &lt;code class=&quot;highlighter-rouge&quot;&gt;vector.insert()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Define an empty vector `doubleContainer` that will contain the double data type
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Assign
// -----------------------------------------------------------------------------
// Populate the vector with 10 elements, each with a value of 3.14159
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The original vector will be over-written by assign
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;9.806&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// {9.806, 9.806, 9.806}
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Append
// -----------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// {9.806, 9.806, 9.806, 3.14159}
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Insert - requires an iterator
// -----------------------------------------------------------------------------
// Create an iterator for the vector
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Set a position for the iterator - in this case, after the first element
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Insert a value
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.601&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// {9.806, 5.601, 9.806, 9.806, 3.14159}
&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;assign()&lt;/code&gt; overwrites the vector&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;insert()&lt;/code&gt; requires an iterator as first parameter, not a simple index&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; appends to the vector&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;add-elements-at-a-precise-position&quot;&gt;Add Elements at a Precise Position&lt;/h2&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// emplace() requires an iterator
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uIt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uIt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;David&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The iterator relating to this container is invalidated by `emplace()`.
// To call `emplace()` again, the iterator must be reset.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uIt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uIt&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Elaine&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Name: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, ID: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that if a reallocation is triggered by &lt;code class=&quot;highlighter-rouge&quot;&gt;emplace()&lt;/code&gt; (i.e. the allocated memory block grows), all iterators, pointers and references for the container are invalidated.
If no reallocation occurs, only those pointing to the position and beyond are invalidated. All iterators, pointers and references to elements before position keep referring to the same elements they were referring to before the &lt;code class=&quot;highlighter-rouge&quot;&gt;emplace()&lt;/code&gt; call.&lt;/p&gt;

&lt;h2 id=&quot;more-efficient-appending&quot;&gt;More Efficient Appending&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;vector::emplace_back()&lt;/code&gt; function inserts a new element at the end of the vector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The new element is constructed in place using the provided arguments.&lt;/strong&gt; This avoids a copy action, improving efficiency as compared with &lt;code class=&quot;highlighter-rouge&quot;&gt;push_back()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The allocated storage space will only be extended if the new vector size exceeds the current vector capacity.&lt;/p&gt;

&lt;p&gt;When the vector element is made up of aggregate data (like a struct), the benefits of &lt;code class=&quot;highlighter-rouge&quot;&gt;emplace_back()&lt;/code&gt; vs &lt;code class=&quot;highlighter-rouge&quot;&gt;push_back()&lt;/code&gt; may be negated. In this case, you should use an initialiser list constructor in the data structure, which will allow the new element to be constructed in-place without a copy.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// `emplace_back()` with aggregate data
// -------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Initialiser list constructor.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;author&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;author&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;c1&quot;&gt;// Initialise a vector of Books
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Reserve memory - vector will hold up to 20 elements before re-allocation is necessary
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reserve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// When using `push_back()`, a temporary object of appropriate type is created and initialized
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;A Scanner Darkly&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Philip K Dick&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;15.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...has the same performance as `push_back()`, because a temporary `Book` is constructed:
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;777&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Guards Guards!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Terry Pratchett&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;9.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// However, the following works if the Struct has an initialiser list constructor:
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;emplace_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;999&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Idoru&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;William Gibson&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;9.99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;clear&quot;&gt;Clear&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;clear()&lt;/code&gt; method removes all elements:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Populate the vector with 10 elements, each with a value of 3.14159
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// `doubleContainer` now has 10 elements
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;doubleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// `doubleContainer` now has 0 elements
&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;erase&quot;&gt;Erase&lt;/h2&gt;
&lt;p&gt;Deletes a single element from a vector.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Add 10 elements to the vector
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;intArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&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;c1&quot;&gt;// intArray vector is now {0,1,2,3,4,5,6,7,8,9}
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Delete 5th element
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// intAarray vector is now {0,1,2,3,5,6,7,8,9}
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;erase-based-on-a-predicate&quot;&gt;Erase Based on a Predicate&lt;/h2&gt;
&lt;p&gt;You can combine &lt;code class=&quot;highlighter-rouge&quot;&gt;erase&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;std::remove_if()&lt;/code&gt; from the stl &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;algorithm&amp;gt;&lt;/code&gt; header to remove elements in the collection based on a predicate:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&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;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Predicate is a lambda that returns 0 if the element is even, 1 otherwise.
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// IN this case, `remove-if` removes odd elements.
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove_if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&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;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;}),&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;optimisation&quot;&gt;Optimisation&lt;/h2&gt;
&lt;p&gt;When the memory allocated for your vector is exceeded as the vector grows, a re-allocation is triggered. Re-allocation is resource-expensive and should be avoided if possible.&lt;/p&gt;

&lt;p&gt;One simple way of avoiding unecessary reallocation is to set a rational capacity for the vector with &lt;a href=&quot;http://www.cplusplus.com/reference/vector/vector/reserve/&quot;&gt;vector.reserve()&lt;/a&gt;. If you do this, re-allocation won’t occur until you exceed the defined reserve.&lt;/p&gt;

&lt;p&gt;The method &lt;code class=&quot;highlighter-rouge&quot;&gt;vector.reserve(n)&lt;/code&gt; sets the vector capacity such that n elements can be contained. If &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; is greater than the current vector capacity the container storage will be reallocated, increasing its capacity to &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; (or greater). &lt;code class=&quot;highlighter-rouge&quot;&gt;vector.reserve()&lt;/code&gt; has no effect on vector size and does not alter the vector elements.&lt;/p&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; is less than the current capacity the function call does not cause a reallocation and the vector capacity is not affected.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm&quot;&gt;Beginner Tutorial on Vectors&lt;/a&gt; - despite the name, this is a really comprehensive article&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PocJ5jXv8No&quot;&gt;Great intro video to vectors&lt;/a&gt; by TheChernoProject&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=HcESuwmlHEY&quot;&gt;Advanced vectors video&lt;/a&gt; by TheChernoProject - optimising useage of the vector class&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/container/vector/push_back&quot;&gt;std::vector::push_back()&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/vector/vector/emplace_back/&quot;&gt;std::vector::emplace_back()&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cplusplus.com/reference/vector/vector/reserve/&quot;&gt;std::vector::reserve())&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/container/vector&quot;&gt;std::vector&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/20603750/3590673&quot;&gt;push_back() vs emplace_back()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 20 Feb 2018 09:26:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2018/02/introduction-to-vectors-in-c++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/02/introduction-to-vectors-in-c++/</guid>
      </item>
      
    
      
      <item>
        <title>Generic Programming - Simple C++ Templates</title>
        <description>&lt;p&gt;C++ is a strongly typed language - all variables must have a specific type, either explicitly defined by the programmer or inferred during compilation. However, function operations are often identical regardless of the data type being operated on.
For example, the body of a function that sums two numbers will be identical for both &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;float&lt;/code&gt; types.&lt;/p&gt;

&lt;p&gt;C++ allows generic functions to be created using &lt;strong&gt;templates&lt;/strong&gt;. This means that the function can work on many different data types without being rewritten for each one. The template generates an ordinary type or function when it is compiled, based on the arguments supplied to the template.&lt;/p&gt;

&lt;h2 id=&quot;simple-template&quot;&gt;Simple Template&lt;/h2&gt;
&lt;p&gt;Simple template definition where all input parameters and return variables are of the same type:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Define the template
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;genericSumTwo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;floatA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;floatB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.44&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use the template with `int` type
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;genericSumTwo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Outputs 4 */&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use the template with `float` type
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;genericSumTwo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;floatA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;floatB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Outputs: 4.66 */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;template-with-different-data-types-input&quot;&gt;Template with Different Data Types Input&lt;/h2&gt;
&lt;p&gt;Templates can accept different data types - with the return data type specified in the template definition:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Template accepts multiple variable types
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input2&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input2&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input1&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input2&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;c1&quot;&gt;// Usage
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getBigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Returns result as a float: 2.22 */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This definition allows different variable types as input parameters, and specifies that the return type will be the same as the type of the first supplied parameter (in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;T&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;specify-values---non-type-parameters&quot;&gt;Specify Values - Non-type Parameters&lt;/h2&gt;
&lt;p&gt;You can also specify values as part of the template specification:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_size&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, the class has a member &lt;code class=&quot;highlighter-rouge&quot;&gt;m_Array&lt;/code&gt; which is initialised with &lt;code class=&quot;highlighter-rouge&quot;&gt;N&lt;/code&gt; elements of type &lt;code class=&quot;highlighter-rouge&quot;&gt;T&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The template is invoked like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// The object will have a member m_Array, an array of ints with size 10.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/y097fkab.aspx&quot;&gt;Templates definition, Microsoft Developer Network&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/cplusplus/cpp_templates.htm&quot;&gt;Tutorials Point C++ Templates&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/cpp/cpp/templates-cpp&quot;&gt;Templates, MSVC docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 07 Feb 2018 11:05:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2018/02/generic-programming-simple-c++-templates/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/02/generic-programming-simple-c++-templates/</guid>
      </item>
      
    
      
      <item>
        <title>Define User Input From an Integer List in C++</title>
        <description>&lt;p&gt;There are many ways to collect user input. In this example a user is prompted to make a selection from a numbered list. This sets the &lt;code class=&quot;highlighter-rouge&quot;&gt;int choice&lt;/code&gt; variable, which can then be used to control programme flow.&lt;/p&gt;

&lt;p&gt;The possible values for user selection, along with a related string label for each value are set up using a &lt;code class=&quot;highlighter-rouge&quot;&gt;struct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Input is handled by &lt;code class=&quot;highlighter-rouge&quot;&gt;std::getline()&lt;/code&gt;, with the input converted to an integer by means of the &lt;code class=&quot;highlighter-rouge&quot;&gt;std::stringstream&lt;/code&gt; operator &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&amp;gt;&lt;/code&gt;. I’ve done it this way rather than using &lt;code class=&quot;highlighter-rouge&quot;&gt;std::cin&lt;/code&gt; so that an empty return can be handled and interpreted as the default value, if this has been set in the &lt;code class=&quot;highlighter-rouge&quot;&gt;selectAction()&lt;/code&gt; function call.&lt;/p&gt;

&lt;h2 id=&quot;example-code&quot;&gt;Example Code&lt;/h2&gt;
&lt;p&gt;Compile this using c++11 standards. for example: &lt;code class=&quot;highlighter-rouge&quot;&gt;g++ -o test -std=c++11 test.cpp&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt; // Needed for any_of()
#include &amp;lt;string&amp;gt;
#include &amp;lt;map&amp;gt;
#include &amp;lt;sstream&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selectAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultChoice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userChoice&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This program prompts a user for input.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Pass in a default value 1
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;userChoice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selectAction&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Choice made: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userChoice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;selectAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultChoice&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;c1&quot;&gt;// Create a data structure `optionPair` so that values may be associated with
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// labels, and initialize an array of `optionPair` elements.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optionPair&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&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;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&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;s&quot;&gt;&quot;Label for Option 1&quot;&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Label for Option 2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&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;s&quot;&gt;&quot;Label for Option 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&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;c1&quot;&gt;// Create an array of valid input values
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optionPair&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validChoices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;validChoices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validChoice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&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;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt; &lt;span class=&quot;o&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Please select an option:&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;) &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stringstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tempStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Is it empty? User just hit return
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tempStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&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;n&quot;&gt;choice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// The user entered something, so convert it to an integer. If the
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// entry is not a number, it will be transformed to 0.
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;tempStream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&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;c1&quot;&gt;// `[&amp;amp;]` specifies that the lambda uses variable capture - needed here
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// since the lambda accesses the `choice` variable.
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;validChoice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;any_of&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validChoices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validChoices&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;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defaultChoice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// User entered return &amp;amp; a default exists - return the default
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultChoice&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validChoice&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;c1&quot;&gt;// User selection returned if valid
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choice&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;c1&quot;&gt;// User feedback for invalid entry
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;You've entered an invalid selection.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Please enter a number from the specified list. Thanks.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I’m sure there are better ways to allow users to choose from  a list of integer values - please leave a comment if you have a suggestion.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/cpp_standard_library/cpp_algorithm_any_of.htm&quot;&gt;Check if an array contains a value using &lt;code class=&quot;highlighter-rouge&quot;&gt;any_of()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cprogramming.com/c++11/c++11-lambda-closures.html&quot;&gt;Lambda functions in C++&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/4999719/3590673&quot;&gt;There is a case for using getline instead of std::cin&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.keithschwarz.com/cs106l/fall2010/course-reader/Ch3_Streams.pdf&quot;&gt;Keith Schwarz lecture notes on Streams&lt;/a&gt; (PDF)&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 04 Feb 2018 11:37:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2018/02/define-user-input-from-an-integer-list-in-c++/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/02/define-user-input-from-an-integer-list-in-c++/</guid>
      </item>
      
    
      
      <item>
        <title>Beginner C++ Functions</title>
        <description>&lt;p&gt;This article is an ongoing summary of my notes on functions in C++. Please don’t assume that what you read here is accurate. For a more complete description of functions in C++, check the references presented below.&lt;/p&gt;

&lt;p&gt;Functions in C++ provide a way to group statements. Functions consist of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A name&lt;/li&gt;
  &lt;li&gt;A list of parameters (which may be zero)&lt;/li&gt;
  &lt;li&gt;A body - which consists of statements enclosed with curly braces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast to scripting languages like JavaScript and PHP, functions in C++ must be declared if they are to be used before their definition.&lt;/p&gt;

&lt;p&gt;Every C++ programme has at least one function called &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;function-declaration-in-c&quot;&gt;Function Declaration in C++&lt;/h2&gt;
&lt;p&gt;A function declaration specifies the function name and the type of data that it returns and accepts. The declaration is terminated with a semi-colon.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;n&quot;&gt;return_type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter1_type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter2_type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// or simply:
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter1_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter2_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Specific example of function declaration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Declare a function that sums two float inputs
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumInputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Parameter names are not needed for function declaration, so this is also valid:
&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumInputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;function-definition-in-c&quot;&gt;Function Definition in C++&lt;/h2&gt;
&lt;p&gt;The function definition specifies the actual body of the function - the actual grouped statements. The general form of a C++ function definition:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;n&quot;&gt;return_type&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;functionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameters&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;c1&quot;&gt;// Body of the function: statements
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Function terminates either by returning or throwing an exception
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This example doubles an input integer:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doubleInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;declaration-rules&quot;&gt;Declaration Rules&lt;/h2&gt;
&lt;p&gt;If a function is defined after it is used, it must be declared in advance. If the function is defined before it is used, the function declaration is optional. However, it is considered good practice to list function declarations at the top of the header file. If the function is defined in a header file which is included in the main programme, the function declaration is not strictly necessary since the header file is included before the function is called.&lt;/p&gt;

&lt;h2 id=&quot;best-practices&quot;&gt;Best Practices&lt;/h2&gt;
&lt;p&gt;If a variable passed as a function parameter will not be modified in the function, it is considered best practice to declare the variable as &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; so that it can’t be changed:&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/functions&quot;&gt;cppreference.com article on functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tutorialspoint.com/cplusplus/cpp_functions.htm&quot;&gt;Tutorials Point article on C++ functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sat, 13 Jan 2018 11:10:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2018/01/beginner-c++-functions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2018/01/beginner-c++-functions/</guid>
      </item>
      
    
      
      <item>
        <title>Securely Erase A Drive from the Linux Command Line</title>
        <description>&lt;p&gt;If a disk contains secure information, it may need to be securely erased.&lt;/p&gt;

&lt;p&gt;This article outlines a simple disk-wipe procedure for the Linux command line. Tested on Ubuntu 16.04.&lt;/p&gt;

&lt;h2 id=&quot;determine-the-target-drive&quot;&gt;Determine the Target Drive&lt;/h2&gt;
&lt;p&gt;To find the drive, run the &lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; command. This will output drive name and mount point:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lsblk
&lt;span class=&quot;c&quot;&gt;# Typical output:&lt;/span&gt;
NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0 465.8G  0 disk
├─sda1                                          8:1    0   512M  0 part  /boot/efi
├─sda2                                          8:2    0   488M  0 part  /boot
└─sda3                                          8:3    0 464.8G  0 part
  └─sda3_crypt                                252:0    0 464.8G  0 crypt
    ├─ubuntu--vg-root                         252:1    0 448.8G  0 lvm   /
    └─ubuntu--vg-swap_1                       252:2    0    16G  0 lvm
      └─cryptswap1                            252:3    0    16G  0 crypt &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;SWAP]
sdb                                             8:16   0   1.8T  0 disk
└─sdb1                                          8:17   0   1.8T  0 part  /media/datadrive
sdc                                             8:32   1   7.5G  0 disk
└─sdc1                                          8:33   1   7.5G  0 part
  └─luks-04235321-8ad9-4631-934c-2c09cfa700e7 252:4    0   7.5G  0 crypt /media/david/secure-data
sdd                                             8:48   1   7.5G  0 disk
└─sdd1                                          8:49   1   7.5G  0 part  /media/david/Thumbdrive
loop0                                           7:0    0  80.5M  1 loop  /snap/core/2462
loop1                                           7:1    0  80.5M  1 loop  /snap/core/2381
loop2                                           7:2    0  79.5M  1 loop  /snap/core/2312
loop3                                           7:3    0 182.6M  1 loop  /snap/atom/9
loop4                                           7:4    0 182.6M  1 loop  /snap/atom/8&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Determine the relevant disk name from this list.&lt;/p&gt;

&lt;h2 id=&quot;double-check-avoid-foot-shooting&quot;&gt;Double Check: Avoid Foot-Shooting&lt;/h2&gt;
&lt;p&gt;When you run the &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; command in the “Wipe the Disk” section of this article, the target disk will be completely overwritten.&lt;/p&gt;

&lt;p&gt;You should therefore &lt;strong&gt;double check that you’re operating on the right drive&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace sdX with your target drive name&lt;/span&gt;
cat /sys/class/block/sdX/device/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;model,vendor&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The output should correspond to the target disk you’re expecting to wipe.&lt;/p&gt;

&lt;h2 id=&quot;wipe-the-disk&quot;&gt;Wipe the Disk&lt;/h2&gt;
&lt;p&gt;This is achieved by writing random data from &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/urandom&lt;/code&gt; to the target disk.&lt;/p&gt;

&lt;p&gt;Block size is set to 1M for the sake of increasing speed - &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; will read and write up to 1M bytes at a time.&lt;/p&gt;

&lt;p&gt;Setting the status option to “progress” prints periodic transfer stats to stderr.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace sdX with your target drive name&lt;/span&gt;
dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/urandom &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdX &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1M &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;progress&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The problem with this method is that &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; just writes indefinitely - until eventually it times out. It works, but it is more time consuming than it needs to be.&lt;/p&gt;

&lt;h2 id=&quot;better-method&quot;&gt;Better Method&lt;/h2&gt;
&lt;p&gt;Use parameters with &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; to wipe a partition/drive:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo fdisk -l /dev/sdX

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
GPT PMBR size mismatch &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;15702015 !&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 15826943&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; will be corrected by w&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;rite&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.
Disk /dev/sdX: 7.6 GiB, 8103395328 bytes, 15826944 sectors
Units: sectors of 1 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 512 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 512 bytes
Sector size &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;logical/physical&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: 512 bytes / 512 bytes
I/O size &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;minimum/optimal&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: 512 bytes / 512 bytes
Disklabel &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;: gpt
Disk identifier: C70EC09A-1A70-4728-9D0C-B4122C401FFA

Device       Start      End  Sectors  Size Type
/dev/sdX1     2048  5122047  5120000  2.5G EFI System
/dev/sdX2  5126144 15701982 10575839    5G Linux filesystem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To wipe whole drive:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2048
&lt;span class=&quot;nv&quot;&gt;End&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;15826944 &lt;span class=&quot;c&quot;&gt;# From line 2 of fdisk output&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;BytesInSector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;512 &lt;span class=&quot;c&quot;&gt;# From line 3 of fdisk output&lt;/span&gt;
dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/urandom &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdX &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BytesInSector&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;End&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;progress&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.forensicswiki.org/wiki/Dd&quot;&gt;Forensics wiki dd Article&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://askubuntu.com/questions/17640/how-can-i-securely-erase-a-hard-drive#17650&quot;&gt;AskUbuntu thread on secure erasure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 12 Dec 2017 09:39:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/12/securely-erase-a-drive-from-the-linux-command-line/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/12/securely-erase-a-drive-from-the-linux-command-line/</guid>
      </item>
      
    
      
      <item>
        <title>Manage and Safely Delete Revisions in WordPress</title>
        <description>&lt;p&gt;In my opinion, &lt;a href=&quot;https://codex.wordpress.org/Revisions&quot;&gt;Revisions&lt;/a&gt; in WordPress are a waste of time. I don’t know anyone that actually uses them - and worse, they can have a serious impact on site performance, especially in the admin area.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Revision Management
Deleting: There is an API function to delete revisions, but there is no UI. That can certainly change.
&lt;a href=&quot;https://codex.wordpress.org/Revisions&quot;&gt;WordPress Codex, Revisions&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Personally, I find this ridiculous - it means that for the average user every time a post is updated the database gets a bit more bloated - and there is no UI to remove this bloat.&lt;/p&gt;

&lt;h2 id=&quot;when-to-be-concerned&quot;&gt;When to be Concerned&lt;/h2&gt;
&lt;p&gt;You may hit a 500 server error when trying to access an edit page for content that has a lot of associated revisions.&lt;/p&gt;

&lt;p&gt;Editing a reasonably sized page with hundreds of revisions can cause problems, even with 256MB server memory available. &lt;a href=&quot;https://core.trac.wordpress.org/ticket/34560&quot;&gt;This trac ticket&lt;/a&gt; outlines the problem nicely. I had to deal with this exact scenario today, which prompted this post.&lt;/p&gt;

&lt;p&gt;Enabling error logging may give you a message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;14-Mar-2018 10:43:37 UTC] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;tried to allocate 20480 bytes&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /var/www/html/example.com/web/wp/wp-includes/meta.php on line 840&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…you’ll find a similar message in your Apache logs.&lt;/p&gt;

&lt;h2 id=&quot;increase-available-memory&quot;&gt;Increase Available Memory&lt;/h2&gt;
&lt;p&gt;This is a band-aid solution, but increasing the available memory can provide an instant fix, and buy some time. Under Ubuntu, edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/php/7.0/apache2/php.ini&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;; &lt;span class=&quot;n&quot;&gt;Maximum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;may&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consume&lt;/span&gt; (&lt;span class=&quot;n&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MB&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;M&lt;/span&gt;)
; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;://&lt;span class=&quot;n&quot;&gt;php&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt;-&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;
; &lt;span class=&quot;n&quot;&gt;Bump&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;up&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memory&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;within&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reasonable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bounds&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;memory_limit&lt;/span&gt; = &lt;span class=&quot;m&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;M&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;IMPORTANT: Restart Apache for the changes to take effect. You could also add a directive to a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file if you’re using one, or add a directive in an Apache virtual host configuration.&lt;/p&gt;

&lt;p&gt;Now that the client has stopped panicking, you can fix the real problem: Revisions.&lt;/p&gt;

&lt;h2 id=&quot;tldr-delete-revisions&quot;&gt;TLDR; Delete Revisions&lt;/h2&gt;
&lt;p&gt;You need MySQL access to delete revisions.&lt;/p&gt;

&lt;p&gt;Get a MySQL command prompt, using your target database:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql -u root -p my_database&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Unfortunately, it’s not quite as simple as just deleting posts from &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_posts&lt;/code&gt; table having a post_type of ‘revision’ - you should also remove associated postmeta  and wp_term_relationships records.&lt;/p&gt;

&lt;p&gt;You can achieve this with the following MySQL/MariaDB commands:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;DELETE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wp_posts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;JOIN&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wp_term_relationships&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;JOIN&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wp_postmeta&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'revision'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This command deletes records from tables a, b and c - defined as wp_posts, wp_term_relationships and wp_postmeta. The rows deleted are determined by these criteria:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Rows in wp_posts table which have a post_type of ‘revision’&lt;/li&gt;
  &lt;li&gt;Rows in wp_term_relationships which have an object_id equal to the ID of a wp_posts ‘revision’ row.&lt;/li&gt;
  &lt;li&gt;Rows in wp_postmeta which have a post_id equal to the ID of a wp_posts ‘revision’ row.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a custom agency build with a lot of custom fields, number 3 is likely to be a big one. For each revision saved, WordPress will add a new postmeta record for each custom field.&lt;/p&gt;

&lt;h2 id=&quot;prevent-revisions&quot;&gt;Prevent Revisions&lt;/h2&gt;
&lt;p&gt;Limit revisions to a rational number, or prevent them altogether - add this to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;define('WP_POST_REVISIONS', 10); // Older revisions will be automatically deleted
define('WP_POST_REVISIONS', FALSE); // No revisions at all&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Revisions&quot;&gt;WordPress Revisions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://core.trac.wordpress.org/ticket/34560&quot;&gt;High memory usage ( and possible server error) editing post with many/large revisions&lt;/a&gt; (trac ticket)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wordpress.stackexchange.com/questions/112312/safest-way-to-bulk-delete-post-revisions&quot;&gt;SO answer, outlining MySQL solution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 14 Nov 2017 20:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/11/manage-and-safely-delete-revisions-in-wordpress/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/11/manage-and-safely-delete-revisions-in-wordpress/</guid>
      </item>
      
    
      
      <item>
        <title>Symlinking to Directories in Linux</title>
        <description>&lt;p&gt;If you need to symlink a directory in Linux, you need to make a distinction. The linked-to directory is intended to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Be&lt;/strong&gt; the symlink: navigating to the symlink is equivalent to navigating to the linked directory&lt;/li&gt;
  &lt;li&gt;Be accessed via a link within the linking directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you intend the former, you need to be careful that the &lt;strong&gt;directory does not already exist&lt;/strong&gt; - if it does, the symlink will be placed inside the existing directory.&lt;/p&gt;

&lt;h2 id=&quot;example-the-directory-is-the-symlink&quot;&gt;Example: The Directory is the Symlink&lt;/h2&gt;
&lt;p&gt;In this case, the ‘directory’ &lt;code class=&quot;highlighter-rouge&quot;&gt;path/to/current&lt;/code&gt; will contain the files from &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/target&lt;/code&gt;. Crucially, &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/current&lt;/code&gt; does not exist.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# /path/to/current does not exist&lt;/span&gt;
ln -s /path/to/target path/to/current

&lt;span class=&quot;c&quot;&gt;# cd to the parent directory and list contents...&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;path/to &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ls -la
&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
drwxrwxr-x 2 david david 4096 Oct 18 21:01 ./
drwxrwxr-x 8 david david 4096 Oct 18 21:01 ../
lrwxrwxrwx 1 david david    4 Oct 18 21:01 current -&amp;gt; /path/to/target/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, to access files in &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/target&lt;/code&gt; via the symlink you would reference &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/current&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;path/to/current &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ls -la
&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
drwxrwxr-x 2 david david 4096 Oct 18 21:03 ./
drwxrwxr-x 7 david david 4096 Oct 18 21:09 ../
-rw-rw-r-- 1 david david    0 Oct 18 21:02 file-1
-rw-rw-r-- 1 david david    0 Oct 18 21:02 file-2
&lt;span class=&quot;c&quot;&gt;# Where file-1 and file-2 are contained in /path/to/target&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example-directory-contains-the-symlink&quot;&gt;Example: Directory Contains the Symlink&lt;/h2&gt;
&lt;p&gt;In this case, the &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/current&lt;/code&gt; directory &lt;strong&gt;does&lt;/strong&gt; exist:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# /path/to/current does exist&lt;/span&gt;
ln -s /path/to/target path/to/current

&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;path/to/current &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ls
&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
drwxrwxr-x 2 david david 4096 Oct 18 21:01 ./
drwxrwxr-x 8 david david 4096 Oct 18 21:01 ../
lrwxrwxrwx 1 david david    4 Oct 18 21:01 target -&amp;gt; /path/to/target&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, to access files in &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/target&lt;/code&gt; via the symlink you would reference &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/current/target&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;rsync---link-dest&quot;&gt;Rsync –link-dest&lt;/h2&gt;
&lt;p&gt;If you’re using the &lt;code class=&quot;highlighter-rouge&quot;&gt;--link-dest&lt;/code&gt; option with &lt;code class=&quot;highlighter-rouge&quot;&gt;rsync&lt;/code&gt; to make incremental backups, make sure you are referencing the correct symlinked reference directory - if not, rsync won’t create hardlinks and your backups will not be incremental. I recently made this error when mis-referencing the most recent backup by dynamically adding a symlink to an already existing directory.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/9104390/3590673&quot;&gt;https://stackoverflow.com/a/9104390/3590673&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 18 Oct 2017 20:30:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/10/symlinking-to-directories-in-linux/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/10/symlinking-to-directories-in-linux/</guid>
      </item>
      
    
      
      <item>
        <title>Access $USER Environment Variable in a Cron Triggered Script in Ubuntu</title>
        <description>&lt;p&gt;When triggering a BASH script in a Cronjob in Ubuntu the script will not have access to the &lt;code class=&quot;highlighter-rouge&quot;&gt;$USER&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;p&gt;This is the case even if the script is trigerred by the user’s crontab. Fortunately this is easily fixed.&lt;/p&gt;

&lt;p&gt;Within the crontab, &lt;code class=&quot;highlighter-rouge&quot;&gt;$LOGNAME&lt;/code&gt; represents the current user - so you can set the &lt;code class=&quot;highlighter-rouge&quot;&gt;$USER&lt;/code&gt; variable before calling your script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open the crontab for your user:&lt;/span&gt;
crontab -e

&lt;span class=&quot;c&quot;&gt;# Sample cron job:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# m h  dom mon dow   command&lt;/span&gt;
05 17 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; env &lt;span class=&quot;nv&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LOGNAME&lt;/span&gt; /usr/local/bin/backup-home&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…you can now use &lt;code class=&quot;highlighter-rouge&quot;&gt;$USER&lt;/code&gt; in the script as usual.&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;Several environment variables are set automatically by cron:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SHELL&lt;/code&gt;: is set to /bin/sh&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;LOGNAME&lt;/code&gt;: is set from the line in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/passwd&lt;/code&gt; corresponding to the crontab’s owner&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HOME&lt;/code&gt;: is set from the line in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/passwd&lt;/code&gt; corresponding to the crontab’s owner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;HOME&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;SHELL&lt;/code&gt; can be overridden in the crontab but &lt;code class=&quot;highlighter-rouge&quot;&gt;LOGNAME&lt;/code&gt; cannot.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man5/crontab.5.htmlS&quot;&gt;Crontab man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 18 Oct 2017 19:52:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/10/access-user-environment-variable-in-a-cron-triggered-script-in-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/10/access-user-environment-variable-in-a-cron-triggered-script-in-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Encrypted Backup Drive in Ubuntu Xenial 16.04</title>
        <description>&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;This article refers to creating a LUKS encrypted backup drive for Ubuntu 16.04 Xenial Xerus - but the steps are likely very similar for any modern Linux distro.&lt;/p&gt;

&lt;p&gt;The exisiting main boot drive is encrypted. The main user’s home drive is also encrypted. The aim is to have a partition on an additional (internal) hard drive which is LUKS encrypted and automatically unlocked on boot. If the disk is removed, it should require a keyfile for decryption. The purpose of this is to locally backup up sensitive data automatically.&lt;/p&gt;

&lt;p&gt;This will ensure that data remains secure - it will be encrypted at rest, and only accessible after booting the OS on the encrypted boot drive - data will be protected by the keyfile, which in turn is inaccessible until the main OS boots, which in turn recquires the encryption passphrase.&lt;/p&gt;

&lt;h2 id=&quot;encrypt-the-partition&quot;&gt;Encrypt the Partition&lt;/h2&gt;
&lt;p&gt;Encrypt the partition using the Gnome Disk utility:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Select and unmount the partion&lt;/li&gt;
  &lt;li&gt;Format partition - select “Encrypted, compatible with Linux systems(LUKS _ Ext4)” in the “Type” dropdown&lt;/li&gt;
  &lt;li&gt;Enter a passphrase when prompted &lt;strong&gt;save this passphrase&lt;/strong&gt;: it can be used to unlock the partition in the event of disaster recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whilst in the Disks utility, you can also mount the partition.&lt;/p&gt;

&lt;p&gt;Note the device name for the partition (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdb*&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;create-a-keyfile-in-the-root-user-home-directory&quot;&gt;Create a Keyfile in the Root User Home Directory&lt;/h2&gt;
&lt;p&gt;Make a keyfile in the &lt;code class=&quot;highlighter-rouge&quot;&gt;root&lt;/code&gt; user home directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir /root/.keyfiles
sudo dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/urandom &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/.keyfiles/hdd-1.key &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1024 &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4
&lt;span class=&quot;c&quot;&gt;# Make this read-only by owner (in this case, root):&lt;/span&gt;
sudo chmod 0400 /root/.keyfiles/hdd-1.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;add-keyfile-to-luks&quot;&gt;Add Keyfile to LUKS&lt;/h2&gt;
&lt;p&gt;LUKS/dm_crypt enabled devices may hold up to 10 different keyfiles/passwords.&lt;/p&gt;

&lt;p&gt;In addition to having the already setup password, we’re going to add this keyfile as additional authorization method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace 'sdX' with the correct device designation&lt;/span&gt;
sudo cryptsetup luksAddKey /dev/sdb2 /root/.keyfiles/hdd-1.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;determine-the-uuid-of-the-partition&quot;&gt;Determine the UUID of the Partition&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 10 Oct 15 10:23 00d75d72-84b0-418f-7dda-2d42002fe045 -&amp;gt; ../../sdX
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-a-mapper&quot;&gt;Create a Mapper&lt;/h2&gt;
&lt;p&gt;Create a mapper in &lt;code class=&quot;highlighter-rouge&quot;&gt;crypttab&lt;/code&gt; that references the keyfile:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# /etc/crypttab&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Append this line - add the relevant UUID - first value is the identifier for this mapping&lt;/span&gt;
sdX_crypt &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00d75d72-84b0-418f-7dda-2d42002fe045 /root/.keyfiles/hdd-1.key luks,discard&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;mount-on-boot&quot;&gt;Mount on Boot&lt;/h2&gt;
&lt;p&gt;To mount the partition on boot:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a mount point&lt;/li&gt;
  &lt;li&gt;Add a command to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fstab&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Create a mount point:&lt;/span&gt;
sudo mkdir /media/secure-hdd

&lt;span class=&quot;c&quot;&gt;# Edit /etc/fstab:&lt;/span&gt;
sudo nano /etc/fstab

&lt;span class=&quot;c&quot;&gt;# /etc/fstab&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Append this line:&lt;/span&gt;
/dev/mapper/sdX_crypt /media/secure-hdd ext4 defaults 0 2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Reboot to check it works.&lt;/p&gt;

&lt;h2 id=&quot;open-without-keyfile&quot;&gt;Open without Keyfile&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Install &lt;code class=&quot;highlighter-rouge&quot;&gt;cryptsetup&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Decrypt the volume &lt;strong&gt;using the original passphrase&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Mount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install cryptsetup:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt install cryptsetup&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Decrypt the volume:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cryptsetup luksOpen /dev/sdX sdX_crypt
&lt;span class=&quot;c&quot;&gt;# Enter passphrase when prompted&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Mount:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir /media/secure-hdd-recovered
sudo mount /dev/mapper/sdX_crypt /media/secure-hdd-recovered&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ubuntuforums.org/archive/index.php/t-837416.html&quot;&gt;Guide from 2008, but largely still relevant&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://askubuntu.com/questions/450895/mount-luks-encrypted-hard-drive-at-boot#541352&quot;&gt;https://askubuntu.com/questions/450895/mount-luks-encrypted-hard-drive-at-boot#541352&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://askubuntu.com/a/63598/463571&quot;&gt;Mount a LUKS encrypted drive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 15 Oct 2017 11:37:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/10/encrypted-backup-drive-in-ubuntu-xenial-16-04/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/10/encrypted-backup-drive-in-ubuntu-xenial-16-04/</guid>
      </item>
      
    
      
      <item>
        <title>LetEncrypt Certbot on Ubuntu Xenial Xerus</title>
        <description>&lt;p&gt;LetsEncrypt is a free, open and automated certificate authority that operates for public benefit. It is a project of the non-profit Internet Security Research Group (ISRG).&lt;/p&gt;

&lt;p&gt;This guide refers to installing and configuring LetsEncrypt and it’s client, Certbot, on Ubuntu 16.04 Xenial Xerus.&lt;/p&gt;

&lt;h2 id=&quot;certbot-the-letsencrypt-client&quot;&gt;Certbot: the LetsEncrypt Client&lt;/h2&gt;
&lt;p&gt;Certbot is a client that allows you to fetch and configure SSL/TLS certificates. It also updates virtual host directives to ensure that site resources redirect to HTTPS.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Certbot is an easy-to-use automatic client that fetches and deploys SSL/TLS certificates for your webserver. Certbot was developed by EFF and others as a client for Let’s Encrypt and was previously known as “the official Let’s Encrypt client” or “the Let’s Encrypt Python client.” Certbot will also work with any other CAs that support the ACME protocol.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://certbot.eff.org/about/&quot;&gt;https://certbot.eff.org/about/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;install-certbot&quot;&gt;Install Certbot&lt;/h2&gt;
&lt;p&gt;See up-to date instructions &lt;a href=&quot;https://certbot.eff.org/#ubuntuxenial-apache&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-certs---specific-domains&quot;&gt;Set Up Certs - Specific Domains&lt;/h2&gt;
&lt;p&gt;If you have pre-existing certs, this may be a good solution:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo certbot --apache -d example.com -d www.example.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This command sets up certificates and creates appropriate virtual host directives that reference the certificates.&lt;/p&gt;

&lt;h2 id=&quot;set-up-certs---interactive-session&quot;&gt;Set Up Certs - Interactive Session&lt;/h2&gt;
&lt;p&gt;You could run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo certbot --apache&lt;/code&gt; instead - this will open an interactive session that will prompt you for various options. If upgrading from a previous version of the LetsEncrypt client, this is probably the best option:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo certbot --apache

&lt;span class=&quot;c&quot;&gt;# This outputs:&lt;/span&gt;
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: acme-v01.api.letsencrypt.org

Which names would you like to activate HTTPS &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;?
-------------------------------------------------------------------------------
1: example.com
2: www.example.com
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to &lt;span class=&quot;k&quot;&gt;select &lt;/span&gt;all options shown &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Enter &lt;span class=&quot;s1&quot;&gt;'c'&lt;/span&gt; to cancel&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The new vhost directives will be created in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; directory in the format &lt;code class=&quot;highlighter-rouge&quot;&gt;example.com-le-ssl.conf&lt;/code&gt;. The vhost configs will be automatically enabled, and a redirect will be written into the corresponding directive for port 80 (the non-HTTP original vhost directive).&lt;/p&gt;

&lt;h2 id=&quot;renew-certs&quot;&gt;Renew Certs&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo certbot renew&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;check-renew&quot;&gt;Check Renew&lt;/h2&gt;
&lt;p&gt;Test that the renew process will work by performing a dry-run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo certbot renew --dry-run&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;automatic-renewal-cronjob&quot;&gt;Automatic Renewal: Cronjob&lt;/h2&gt;
&lt;p&gt;Certificates have a three-month lifespan, so automatic renewal is recommended.&lt;/p&gt;

&lt;p&gt;LetsEncrypt/Certbot sets up a cronjob. This is located at &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/cron.d/certbot&lt;/code&gt;. It looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# /etc/cron.d/certbot: crontab entries for the certbot package&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Upstream recommends attempting renewal twice a day&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Eventually, this will be an opportunity to validate certificates&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# haven't been revoked, etc.  Renewal will only occur if expiration&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# is within 30 days.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SHELL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/bin/sh
&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;/12 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; root &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; -x /usr/bin/certbot -a &lt;span class=&quot;se&quot;&gt;\!&lt;/span&gt; -d /run/systemd/system &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; perl -e &lt;span class=&quot;s1&quot;&gt;'sleep int(rand(3600))'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; certbot -q renew&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The script first checks that &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/bin/certbot&lt;/code&gt; exists and is executable, and that systemd is NOT present before running renew on a random minute of the hour.&lt;/p&gt;

&lt;p&gt;The cronjob:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Runs every twelve hours&lt;/li&gt;
  &lt;li&gt;Tests that &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/bin/certbot&lt;/code&gt; exists and is executable (i.e. certbot is installed)&lt;/li&gt;
  &lt;li&gt;ALSO (&lt;code class=&quot;highlighter-rouge&quot;&gt;-a&lt;/code&gt;) tests that the directory &lt;code class=&quot;highlighter-rouge&quot;&gt;/run/systemd/system&lt;/code&gt; does NOT exist (i.e. systemd is not present on the system)&lt;/li&gt;
  &lt;li&gt;If the previous two conditions are satisfied, pauses for a random number of seconds &amp;lt; 3600&lt;/li&gt;
  &lt;li&gt;When the sleep period has elapsed, &lt;code class=&quot;highlighter-rouge&quot;&gt;certbot renew&lt;/code&gt; runs in quiet mode&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ubuntu-1604-your-cronjob-does-nothing&quot;&gt;Ubuntu 16.04? Your Cronjob Does Nothing!&lt;/h2&gt;
&lt;p&gt;The test command in the cronjob under &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/cron.d/certbot&lt;/code&gt; stops execution if systemd is present - which in the case of Ubuntu, it is.&lt;/p&gt;

&lt;p&gt;In this case, the timing of renewals is controlled in &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/systemd/system/certbot.timer&lt;/code&gt;. Note that the execution of this is controlled in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/systemd/system/timers.target.wants&lt;/code&gt;, which contains a symlink to &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/systemd/system/certbot.timer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/systemd/system/certbot.timer&lt;/code&gt; file looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;[&lt;span class=&quot;n&quot;&gt;Unit&lt;/span&gt;]
&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;Run&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;certbot&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;twice&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;daily&lt;/span&gt;

[&lt;span class=&quot;n&quot;&gt;Timer&lt;/span&gt;]
&lt;span class=&quot;n&quot;&gt;OnCalendar&lt;/span&gt;=*-*-* &lt;span class=&quot;m&quot;&gt;00&lt;/span&gt;,&lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;:&lt;span class=&quot;m&quot;&gt;00&lt;/span&gt;:&lt;span class=&quot;m&quot;&gt;00&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;RandomizedDelaySec&lt;/span&gt;=&lt;span class=&quot;m&quot;&gt;3600&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Persistent&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;

[&lt;span class=&quot;n&quot;&gt;Install&lt;/span&gt;]
&lt;span class=&quot;n&quot;&gt;WantedBy&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;timers&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This timer runs the service &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/systemd/system/certbot.service&lt;/code&gt;, which looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;[&lt;span class=&quot;n&quot;&gt;Unit&lt;/span&gt;]
&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;Certbot&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Documentation&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;:///&lt;span class=&quot;n&quot;&gt;usr&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;share&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;python&lt;/span&gt;-&lt;span class=&quot;n&quot;&gt;certbot&lt;/span&gt;-&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Documentation&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;https&lt;/span&gt;://&lt;span class=&quot;n&quot;&gt;letsencrypt&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;readthedocs&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;en&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;latest&lt;/span&gt;/
[&lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;]
&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;oneshot&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ExecStart&lt;/span&gt;=/&lt;span class=&quot;n&quot;&gt;usr&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;bin&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;certbot&lt;/span&gt; -&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;renew&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PrivateTmp&lt;/span&gt;=&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that by default, a service is activated with the same name (excluding suffix) as the timer - so &lt;code class=&quot;highlighter-rouge&quot;&gt;certbot-timer&lt;/code&gt; activates &lt;code class=&quot;highlighter-rouge&quot;&gt;certbot-service&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;support-letsencrypt&quot;&gt;Support LetsEncrypt&lt;/h2&gt;
&lt;p&gt;You can support LetsEncrypt and Certbot by &lt;a href=&quot;https://letsencrypt.org/donate/&quot;&gt;donating here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-set-up-let-s-encrypt-certificates-for-multiple-apache-virtual-hosts-on-ubuntu-16-04&quot;&gt;DO Guide: LetsEncrypt for multiple Apache Vhosts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arashmilani.com/post?id=95&quot;&gt;LetsEncrypt for nginx&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://certbot.eff.org/docs/using.html#renewing-certificates&quot;&gt;Certbot docs on renewal&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://community.letsencrypt.org/t/certbot-cron-and-hooks/19541&quot;&gt;LetsEncrypt Forum: cron and hooks&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://redlua.com/post/setup-lets-encrypt-with-nginx/#automating-certbot&quot;&gt;LetsEncrypt automation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man5/systemd.timer.5.html&quot;&gt;Systemd Timer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 23 Sep 2017 11:57:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/09/letencrypt-certbot-on-ubuntu-xenial-xerus/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/09/letencrypt-certbot-on-ubuntu-xenial-xerus/</guid>
      </item>
      
    
      
      <item>
        <title>Iterating Over Dictionary in Python</title>
        <description>&lt;p&gt;A dictionary in Python is a collection of unordered values accessed by key rather than index. Dictionary elements have no intrinsic order.&lt;/p&gt;

&lt;p&gt;This short article shows several methods for iterating over Python dictionaries.&lt;/p&gt;

&lt;p&gt;The examples in this article are Python 3.&lt;/p&gt;

&lt;p&gt;Example dictionary:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;amount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;payee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Joe Bloggs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;account&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;iterate-via-keys&quot;&gt;Iterate via keys&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}: {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Joe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bloggs&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;iterate-values-only&quot;&gt;Iterate values only&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Joe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bloggs&lt;/span&gt;
&lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;iterate-over-key-value-pairs&quot;&gt;Iterate over key value pairs&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}: {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Joe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bloggs&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I often confuse this with the PHP &lt;code class=&quot;highlighter-rouge&quot;&gt;foreach&lt;/code&gt; construct - forgetting to chain the &lt;code class=&quot;highlighter-rouge&quot;&gt;items()&lt;/code&gt; method to the dictionary being iterated over.&lt;/p&gt;

&lt;h2 id=&quot;iterate-over-keys-in-the-sorted-order-of-the-keys&quot;&gt;Iterate over keys in the sorted order of the keys&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{}: {}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transaction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Joe&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bloggs&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikibooks.org/wiki/Python_Programming/Dictionaries#Operations_on_Dictionaries&quot;&gt;Operations on Python Dictionaries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 21 Sep 2017 21:08:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/09/iterating-over-dictionary-in-python/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/09/iterating-over-dictionary-in-python/</guid>
      </item>
      
    
      
      <item>
        <title>Upgrading Monero Command Line Interface</title>
        <description>&lt;p&gt;Notes on upgrading Monero command line interface on Ubuntu 16.04 From Wolfram-Warptangent to Helium-Hydra.&lt;/p&gt;

&lt;h2 id=&quot;download-new-binaries&quot;&gt;Download New Binaries&lt;/h2&gt;
&lt;p&gt;Download the binaries, along with the list of hashes that will allow you to verify the download:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Make a suitable directory and move into it&lt;/span&gt;
mkdir ~/monero/helium-hydra &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Download the Monero Linux 64 bit CLI client&lt;/span&gt;
wget https://downloads.getmonero.org/cli/monero-linux-x64-v0.11.0.0.tar.bz2

&lt;span class=&quot;c&quot;&gt;# Download the GPG-signed canonical list of hashes&lt;/span&gt;
wget https://getmonero.org/downloads/hashes.txt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;verify-the-download&quot;&gt;Verify the Download&lt;/h2&gt;
&lt;p&gt;To verify the download, you need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Verify that you have a true copy of hashes.txt&lt;/li&gt;
  &lt;li&gt;Check that the &lt;code class=&quot;highlighter-rouge&quot;&gt;sha256sum&lt;/code&gt; checksum for your downloaded tar file matches the quoted value in &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To verify &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt;, you must install the appropriate GPG key, which is found &lt;a href=&quot;https://github.com/monero-project/monero/tree/master/utils/gpg_keys&quot;&gt;here&lt;/a&gt; in the Monero source code repository (/utils/gpg_keys).&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt; file will state which signature has been used - in this case, we need to add the GPG signature for fluffypony to GPG.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Download the raw public key:&lt;/span&gt;
wget https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/fluffypony.asc

&lt;span class=&quot;c&quot;&gt;# Import this public key to GnuPG:&lt;/span&gt;
gpg --import fluffypony.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now use GnuPG to verify &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt;. From within the same directory as the file, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpg --verify hashes.txt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If the &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt; file is genuine, you should see:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# email has been obfuscated - you should see the correct email in your output&lt;/span&gt;
gpg: Signature made Tue 12 Sep 2017 21:37:04 IST using RSA key ID 1CCD4FCD
gpg: Good signature from &lt;span class=&quot;s2&quot;&gt;&quot;Riccardo Spagni &amp;lt;***@******.net&amp;gt;&quot;&lt;/span&gt;
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: BDA6 BD70 42B7 21C4 67A9  759D 7455 C5E3 C0CD CEB9
     Subkey fingerprint: 94B7 38DD 3501 32F5 ACBE  EA1D 5543 2DF3 1CCD 4FCD&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now use &lt;code class=&quot;highlighter-rouge&quot;&gt;hashes.txt&lt;/code&gt; to verify the Monero download:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sha256sum -c hashes.txt 2&amp;gt;&amp;amp;1 | grep OK

&lt;span class=&quot;c&quot;&gt;# Successful verification will look like this:&lt;/span&gt;
monero-linux-x64-v0.11.0.0.tar.bz2: OK&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;extract&quot;&gt;Extract&lt;/h2&gt;
&lt;p&gt;Extract the files from the downloaded tarball:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/monero/helium-hydra
tar -xjvf monero-linux-x64-v0.11.0.0.tar.bz2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Move/copy Wallet files from old to new directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace 'MyWallet' with your wallet name - note lack of spaces after commas&lt;/span&gt;
cp ~/monero/wolfram-warptangent/monero-v0.10.3.1/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;MyWallet,MyWallet.address.txt,MyWallet.keys&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; ~/monero/helium-hydra/monero-v0.11.0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;run-monero&quot;&gt;Run Monero&lt;/h2&gt;
&lt;p&gt;When you move into the new Monero directory and run &lt;code class=&quot;highlighter-rouge&quot;&gt;./monerod&lt;/code&gt;, it should start syncing to the forked blockchain - it will not need to download the Monero blockchain from scratch.&lt;/p&gt;

&lt;p&gt;In my case, I had already synced after the hard-fork with the previous CLI client, and this caused a problem. To get around this, remove some downloaded blocks by running &lt;code class=&quot;highlighter-rouge&quot;&gt;monero-blockchain-import&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Get rid of the most recent 1000 blocks - it may be necessary to remove more&lt;/span&gt;
./monero-blockchain-import --pop-blocks 1000&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;connect-up-and-run-monero&quot;&gt;Connect Up and Run Monero&lt;/h2&gt;
&lt;p&gt;A convenient way to manage Monero version upgrades is to create symlinks to Monero executables within a directory that is in your &lt;code class=&quot;highlighter-rouge&quot;&gt;$PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, after you download and verify the ‘helium-hydra’ Monero binaries, you might symlink to relevant files from within your &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt; directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ln -s ~/monero/helium-hydra/monero-v0.11.0.0/monerod monerod
sudo ln -s ~/monero/helium-hydra/monero-v0.11.0.0/monero-wallet-cli monero-wallet-cli&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt; directory now contains the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lrwxrwxrwx  1 root  root       56 Sep 19 10:35 monerod -&amp;gt; /home/david/monero/helium-hydra/monero-v0.11.0.0/monerod&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
lrwxrwxrwx  1 root  root       66 Sep 19 10:36 monero-wallet-cli -&amp;gt; /home/david/monero/helium-hydra/monero-v0.11.0.0/monero-wallet-cli&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To run &lt;code class=&quot;highlighter-rouge&quot;&gt;monerod&lt;/code&gt; from the helium-hydra package, just run &lt;code class=&quot;highlighter-rouge&quot;&gt;monerod&lt;/code&gt; in your terminal.
Likewise, &lt;code class=&quot;highlighter-rouge&quot;&gt;monero-wallet-cli&lt;/code&gt; will run the correct wallet CLI binary.&lt;/p&gt;
</description>
        <pubDate>Tue, 19 Sep 2017 19:29:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/09/upgrading-monero-command-line-interface/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/09/upgrading-monero-command-line-interface/</guid>
      </item>
      
    
      
      <item>
        <title>Attach Click Event to Many Elements in Javascript</title>
        <description>&lt;p&gt;Plain JavaScript: loop through elements by class name and attach a click event using &lt;code class=&quot;highlighter-rouge&quot;&gt;Array.forEach&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;getElementsByClassName()&lt;/code&gt; method returns a &lt;a href=&quot;https://developer.mozilla.org/en/docs/Web/API/HTMLCollection&quot;&gt;HTMLCollection&lt;/a&gt; object. This needs to be converted to an array before iterating with &lt;code class=&quot;highlighter-rouge&quot;&gt;Array.forEach()&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;displayAddress&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/td&amp;gt;&amp;lt;td class=&quot;selector&quot; title=&quot;Double click to select&quot;&amp;gt;${address.address}&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/tr&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/td&amp;gt;&amp;lt;td class=&quot;selector&quot; title=&quot;Double click to select&quot;&amp;gt;${address.secret}&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/tr&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Public&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/td&amp;gt;&amp;lt;td class=&quot;form-selector&quot;&amp;gt;${address.publicKey}&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/tr&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Private&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/td&amp;gt;&amp;lt;td&amp;gt;${address.privateKey}&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;td&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/tr&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/table&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;displayAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;innerHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;displayAddress&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// The forEach method requires an array, rather than a HTML collection&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;selectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByClassName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'selector'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;selectors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'click'&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;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Send the text content of the clicked element for processing&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;copyToClipboard&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&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;p&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;c1&quot;&gt;// Prompt user to copy text to clipboard&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;copyToClipboard&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;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Copy to clipboard: Ctrl+C, Enter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 05 Sep 2017 10:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/09/attach-click-event-to-many-elements-in-javascript/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/09/attach-click-event-to-many-elements-in-javascript/</guid>
      </item>
      
    
      
      <item>
        <title>Verify and Setup Litecoin Core</title>
        <description>&lt;p&gt;This guide refers to downloading and verifying Litecoin Core in Ubuntu 16.04. The guidelines should be pretty much the same for any Debian-based Linux distro.&lt;/p&gt;

&lt;h2 id=&quot;download-the-litecoin-core-client--signatures-document&quot;&gt;Download the Litecoin Core Client &amp;amp; Signatures Document&lt;/h2&gt;
&lt;p&gt;Download the relevant Litecoin Core &lt;code class=&quot;highlighter-rouge&quot;&gt;.tar&lt;/code&gt; file and the GPG signatures document.&lt;/p&gt;

&lt;p&gt;To keep things organised, create a dedicated subdirectory and move into it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir ~/Downloads/litecoin &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Download the provided tar - at the time of writing this is:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# litecoin-0.14.2-x86_64-linux-gnu.tar.gz&lt;/span&gt;
curl https://download.litecoin.org/litecoin-0.14.2/linux/litecoin-0.14.2-x86_64-linux-gnu.tar.gz

&lt;span class=&quot;c&quot;&gt;# Download the Litecoin hash signatures document to the same directory&lt;/span&gt;
curl https://download.litecoin.org/litecoin-0.14.2/linux/litecoin-0.14.2-linux-signatures.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;verify-the-signatures-document&quot;&gt;Verify the Signatures Document&lt;/h2&gt;
&lt;p&gt;Download a copy of the Litecoin Core PGP key, as shown on the main website:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;https://pgp.mit.edu/pks/lookup?op=get&amp;amp;search=0xFE3348877809386C&quot;&lt;/span&gt; | sed -n &lt;span class=&quot;s1&quot;&gt;'1,/&amp;lt;pre&amp;gt;/d;/&amp;lt;\/pre&amp;gt;/q;p'&lt;/span&gt; &amp;gt; litecoin.pub.key
&lt;span class=&quot;c&quot;&gt;# Parsing HTML like this is bad...you should just curl the document and manually&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# copy the key from between the &amp;lt;pre&amp;gt; tags, or hit the URL in your browser and copy the key.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# I used sed out of interest.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now you can import the Litecoin public key:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpg --import litecoin.pub.key

&lt;span class=&quot;c&quot;&gt;# Check that it installed correctly:&lt;/span&gt;
gpg --list-keys&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once the key is installed, you can verify the document that contains the hash signatures:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpg --verify litecoin-0.14.2-linux-signatures.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;checksum&quot;&gt;Checksum&lt;/h2&gt;
&lt;p&gt;You can then safely use the signatures document to verify that the checksum of the download matches the expected checksum provided by the project:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sha256sum -c litecoin-0.14.2-linux-signatures.asc 2&amp;gt;&amp;amp;1 | grep OK

&lt;span class=&quot;c&quot;&gt;# Or:&lt;/span&gt;
grep litecoin-0.14.2-x86_64-linux-gnu.tar.gz litecoin-0.14.2-linux-signatures.asc | sha256sum --check

&lt;span class=&quot;c&quot;&gt;# In either case, a successful return will be:&lt;/span&gt;
litecoin-0.14.2-x86_64-linux-gnu.tar.gz: OK

&lt;span class=&quot;c&quot;&gt;# ... this means that the SHA256 hashes match.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;glitch-in-signatures-document&quot;&gt;Glitch in Signatures Document&lt;/h2&gt;
&lt;p&gt;The Signatures document contains Windows line endings, which causes the &lt;code class=&quot;highlighter-rouge&quot;&gt;sha256sum&lt;/code&gt; check to fail (on Ubuntu, likely also on Mac):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sha256sum -c litecoin-0.14.2-linux-signatures.asc 2&amp;gt;&amp;amp;1 | grep OK
&lt;span class=&quot;c&quot;&gt;# returns blank&lt;/span&gt;

grep litecoin-0.14.2-x86_64-linux-gnu.tar.gz litecoin-0.14.2-linux-signatures.asc | sha256sum --check
&lt;span class=&quot;c&quot;&gt;# returns:&lt;/span&gt;
sha256sum: &lt;span class=&quot;s1&quot;&gt;'litecoin-0.14.2-x86_64-linux-gnu.tar.gz'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;': No such file or directory
: FAILED open or read4-linux-gnu.tar.gz
sha256sum: WARNING: 1 listed file could not be read&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Fortunately this is easily remedied. Open the signatures file in Gedit, and ‘Save As’ with the same filename. You’ll be given an option for ‘Line Ending’, for which you should choose Unix/Linux.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/5218716/3590673&quot;&gt;sed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Fri, 01 Sep 2017 19:33:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/09/verify-and-setup-litecoin-core/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/09/verify-and-setup-litecoin-core/</guid>
      </item>
      
    
      
      <item>
        <title>Bitcoin Cold Wallet Setup Bash Script</title>
        <description>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; - the script in this article will not work with Bitcoin Core v0.15.0 and higher. Check out my &lt;a href=&quot;https://github.com/DavidCWebs/airgap-core-utilities&quot;&gt;airgap utilities repo on GitHub&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;If you want to examine a cold wallet in an offline Tails session, you’ll need to reference the Bitcoin binaries in your persistent volume. You’ll also need to move the required wallet into the Bitcoin data directory - which won’t exist until you run &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt; for the first time in the session.&lt;/p&gt;

&lt;p&gt;This gets tedious, so I wrote this script to connect everything up.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Open a Bitcoin Core cold wallet in an offline Tails session.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This script runs a simple zenity GUI which prompts the user to select:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - The cold wallet file&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - The `bitcoin-qt` binary&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Both of these files will probably be on your persistent volume.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;set_cold_wallet &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;WALLET_FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;zenity --file-selection --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Select a Cold Wallet to run.&quot;&lt;/span&gt; --filename&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in
    &lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$WALLET_FILE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
    1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;No file selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
    -1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;An unexpected error has occurred.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;set_bitcoin_binary &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;BITCOIN_CORE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;zenity --file-selection --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Select the bitcoin-qt binary.&quot;&lt;/span&gt; --filename&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in
    &lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BITCOIN_CORE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
    1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;No file selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
    -1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;An unexpected error has occurred.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;create_symlink &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~/.bitcoin
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; ! -d &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Creating &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
    mkdir &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fi

  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; -L &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;/cold-wallet.dat &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Remove exisiting symlink, &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/cold-wallet.dat&quot;&lt;/span&gt;
    rm &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/cold-wallet.dat
  &lt;span class=&quot;k&quot;&gt;fi

  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Make a symlink &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/cold-wallet.dat pointing to &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WALLET_FILE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  ln -s &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WALLET_FILE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/cold-wallet.dat
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;run_wallet &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Starting Bitcoin Core with wallet &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;WALLET_FILE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BITCOIN_CORE&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; -wallet&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cold-wallet.dat
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Run this script&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ONLY RUN IN A COLD ENVIRONMENT.&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you wish to proceed? [y/N]&quot;&lt;/span&gt; PROCEED
&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$PROCEED&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  set_cold_wallet
  set_bitcoin_binary
  create_symlink
  run_wallet
  &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;END&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;As of v0.15.0, the Bitcoin Core client does not allow symlinked wallets. As such, &lt;strong&gt;the above script no longer works&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You would need to adjust the script so that it copies your specified cold wallet into the default Bitcoin data directory: (~/.bitcoin/cold-wallet.dat). Rather than rewrite the isolated script, I wrote a set of airgap utilities for Bitcoin/Litecoin core that includes loading a cold wallet into an offline session. The scripts are optimised for an offline Tails session and you can access the package &lt;a href=&quot;https://github.com/DavidCWebs/airgap-core-utilities&quot;&gt;here&lt;/a&gt;. The package allows you to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dump private keys into a symmetrically GPG encrypted file - for super paranoid paper backups&lt;/li&gt;
  &lt;li&gt;Load a fresh copy of Bitcoin/Litecoin core (useful for generating new cold wallets)&lt;/li&gt;
  &lt;li&gt;Load a specified cold wallet into an instance of Bitcoin/Litecoin Core&lt;/li&gt;
  &lt;li&gt;Check the passphrase for a specified cold wallet&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/airgap-core-utilities&quot;&gt;BASH scripts to manage Bitcoin Core/Litecoin Core wallets in an offline Tails session&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 22 Aug 2017 20:07:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/08/set-up-bitcoin-cold-wallet-in-a-live-session-using-a-bash-script/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/08/set-up-bitcoin-cold-wallet-in-a-live-session-using-a-bash-script/</guid>
      </item>
      
    
      
      <item>
        <title>Bitcoin Cold Storage Using a Bitcoin Core Wallet</title>
        <description>&lt;p&gt;This article describes how to:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Create a cold-storage wallet using Bitcoin Core in a live offline Tails session&lt;/li&gt;
  &lt;li&gt;Generate and collect public Bitcoin addresses for the cold wallet&lt;/li&gt;
  &lt;li&gt;Manage the wallet and wallet passphrase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cold wallet is created by running Bitcoin Core in an offline &lt;a href=&quot;https://tails.boum.org/&quot;&gt;Tails&lt;/a&gt; session. Once created, keep the wallet cold - never enter the passphrase within anything other than an offline Tails (or similar) session.&lt;/p&gt;

&lt;p&gt;I’ve written these guidelines for myself as an aid to memory - please use them with caution. If you’re not comfortable using the command line, get a &lt;a href=&quot;https://trezor.io/&quot;&gt;Trezor&lt;/a&gt;, &lt;a href=&quot;https://www.ledgerwallet.com/&quot;&gt;Ledger&lt;/a&gt; or other hardware wallet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t keep your funds on an exchange:&lt;/strong&gt; Loads of exchanges have been hacked, so you’re better off holding funds in a cold wallet of some description.&lt;/p&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;You’ll need a USB drive with a working copy of Tails: download the Tails ISO, verify it, then install Tails on a USB drive using the Tails installer. You’ll then be able to boot into a very secure live environment. Detailed instructions on Tails installation for Linux Debian, Ubuntu and Mint can be found &lt;a href=&quot;https://tails.boum.org/install/debian/usb/index.en.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You will also need the Bitcoin Core binaries, which you can get &lt;a href=&quot;https://bitcoin.org/en/download&quot;&gt;here&lt;/a&gt;. Once you’ve downloaded Bitcoin Core, you should verify that the file hasn’t been tampered with.&lt;/p&gt;

&lt;p&gt;To run Tails, power down your PC, insert the Tails USB drive and boot from the USB. Tails is surprisingly usable - it’s based on Debian and comes bundled with a load of utility and privacy focused software. On a modern computer (and decent USB drive) I find it stable, quick-booting and responsive.&lt;/p&gt;

&lt;h2 id=&quot;encrypted-persistence-volume&quot;&gt;Encrypted Persistence Volume&lt;/h2&gt;
&lt;p&gt;Note that Tails is &lt;em&gt;amnesiac&lt;/em&gt; by design (The “a” in Tails stands for amnesiac) - nothing will be stored from your session unless you set up an encrypted persistent volume.&lt;/p&gt;

&lt;p&gt;The first time you boot into Tails, create an encrypted persistent storage partition on the USB drive - this is straightforward, just follow the instructions &lt;a href=&quot;https://tails.boum.org/doc/first_steps/persistence/index.en.html&quot;&gt;here&lt;/a&gt;. Carefully store the passphrase for your encrypted persistence volume - I recommend &lt;a href=&quot;https://www.keepassx.org/&quot;&gt;KeePassX&lt;/a&gt; for generating and storing strong passwords/passphrases. KeePassX is actually bundled with Tails.&lt;/p&gt;

&lt;p&gt;The encrypted partition (&lt;code class=&quot;highlighter-rouge&quot;&gt;/Persistent&lt;/code&gt;) provides a persistent location for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Bitcoin Core binaries&lt;/li&gt;
  &lt;li&gt;Storing the cold wallet&lt;/li&gt;
  &lt;li&gt;Storing a CSV formatted file listing public Bitcoin addresses to receive funds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you’ve added a persistent storage partition, power down the PC. Mount the USB drive in your regular distro - for which you’ll need the encryption passphrase - and add the Bitcoin Core binaries to the Tails USB drive’s &lt;code class=&quot;highlighter-rouge&quot;&gt;/Persistent&lt;/code&gt; volume.&lt;/p&gt;

&lt;h2 id=&quot;run-bitcoin-core-in-an-offline-tails-session&quot;&gt;Run Bitcoin Core in an Offline Tails Session&lt;/h2&gt;
&lt;p&gt;Temporarily disconnect the computer’s ethernet connection and/or disable the Wifi connection. Boot into your Tails USB disk.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open a terminal and &lt;code class=&quot;highlighter-rouge&quot;&gt;cd&lt;/code&gt; to the Bitcoin Core binaries directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;cd ~/Persistent/bitcoin-x.x.x/bin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;./bitcoin-qt&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Hide the pop-up warning about recent transactions - the instance does not need to sync to the network for our purposes&lt;/li&gt;
  &lt;li&gt;At this point, a new &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt; file will have been created in the root of the data directory(e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bitcoin/wallet.dat&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Encrypt the wallet: in the Bitcoin Core client, click “Settings &amp;gt; Encrypt Wallet”&lt;/li&gt;
  &lt;li&gt;Enter a strong passphrase at the prompt (use &lt;a href=&quot;http://world.std.com/~reinhold/diceware.html&quot;&gt;diceware&lt;/a&gt;, or generate a strong passphrase using KeePassX)&lt;/li&gt;
  &lt;li&gt;Store the passphrase in a secure location - KeePassX is ideal for this&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;view-receiving-addresses&quot;&gt;View Receiving Addresses&lt;/h2&gt;
&lt;p&gt;At this point, Bitcoin Core will have created two receiving addresses that are managed by the wallet. Access these addresses via the Bitcoin Core File menu:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Click “File” &amp;gt; “Receiving Addresses”&lt;/li&gt;
  &lt;li&gt;Click export to export in CSV format&lt;/li&gt;
  &lt;li&gt;Save this file on the persistent drive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“Label” Refers to the “Account” Name. Two unnamed accounts are created by default during wallet setup. Rename these if necessary - right click the label field in the Receiving Addresses view and click “Edit”.&lt;/p&gt;

&lt;p&gt;Note that “accounts” are deprecated in Bitcoin Core, but you’ll find numerous references to accounts in online tutorials and documentation. The API still has lots of references to accounts - for example, to list out addresses, the &lt;code class=&quot;highlighter-rouge&quot;&gt;getaddressesbyaccount&lt;/code&gt; method is required.&lt;/p&gt;

&lt;h2 id=&quot;save-the-wallet&quot;&gt;Save the Wallet!&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; Save the generated wallet to your persistent volume.&lt;/p&gt;

&lt;p&gt;I recommend a logical file naming protocol that involves the date and the words “cold-wallet”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open terminal and copy the wallet to the persistent volume&lt;/span&gt;
cp ~/.bitcoin/wallet.dat ~/Persistent/cold-wallets/20-06-2017-cold-wallet.dat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you don’t explicitly save the wallet file, when you close your Tails session, the wallet will be lost. If you were to send funds to a public address controlled by this wallet, they would be irretrievable.&lt;/p&gt;

&lt;h2 id=&quot;double-check&quot;&gt;Double Check&lt;/h2&gt;
&lt;p&gt;Before sending Bitcoin to addresses managed by the new wallet, Open the saved &lt;code class=&quot;highlighter-rouge&quot;&gt;*.dat&lt;/code&gt; file in an offline Tails session and double check:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It is managing the correct public addresses&lt;/li&gt;
  &lt;li&gt;The encryption passphrase is correct (enter &lt;code class=&quot;highlighter-rouge&quot;&gt;walletpassphrase &quot;yourpassphrase&quot; 5&lt;/code&gt; in console - the correct passphrase should return “null”)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can open a wallet by passing in the &lt;code class=&quot;highlighter-rouge&quot;&gt;-wallet&lt;/code&gt; option when opening Bitcoin Core - BUT the wallet must be located in the Bitcoin core data directory. You can add a symlink to set this up:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ln -s ~/Persistent/cold-wallets/20-06-2017-cold-wallet.dat ~/.bitcoin/cold-wallet.dat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now launch Bitcoin core and reference the cold wallet:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Move into the Bitcoin Core directory&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/Persistent/bitcoin-x.x.x/bin

&lt;span class=&quot;c&quot;&gt;# Launch Bitcoin Core with a specified wallet:&lt;/span&gt;
./bitcoin-qt -wallet&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cold-wallet.dat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I’ve written a utility script that connects up the cold wallet: &lt;a href=&quot;https://github.com/DavidCWebs/bitcoin-cold-wallet-setup&quot;&gt;https://github.com/DavidCWebs/bitcoin-cold-wallet-setup&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;transfer-funds&quot;&gt;Transfer Funds&lt;/h2&gt;
&lt;p&gt;Transfer Bitcoin to one of the public Bitcoin addresses managed by the cold wallet.&lt;/p&gt;

&lt;p&gt;Don’t unlock the cold wallet on any internet-connected machine, or on any machine that might be infected with malware.&lt;/p&gt;

&lt;h2 id=&quot;backup-private-keys&quot;&gt;Backup Private Keys&lt;/h2&gt;
&lt;p&gt;If required, you could dump the private keys of the cold wallet. If you do this, you’ll need to keep these extremely safe. Access to the private keys equates to full control over the Bitcoin. On the plus side, you could store these keys on paper which would ensure that you will always be able to import keys.&lt;/p&gt;

&lt;p&gt;Personally, I have decided not to backup private keys - instead relying on multiple copies of a cold wallet encrypted with a strong passphrase. The wallet can then be safely stored online, since it is effectively useless without the encryption passphrase. Note that if someone gained control of your encrypted wallet without the passphrase, although they would not be able to transfer funds they would be able to access your transaction history. The passphrase should be stored securely (for example, in multiple copies of an encrypted KeePassX database in more than one location).&lt;/p&gt;

&lt;h2 id=&quot;accessing-the-wallet&quot;&gt;Accessing the Wallet&lt;/h2&gt;
&lt;p&gt;To access funds managed by the wallet, you just need to open it in a “hot” Bitcoin Core client. To do this in Ubuntu:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Move the cold wallet into the Bitcoin Core data directory&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-qt&lt;/code&gt;, passing the wallet filename to the “wallet” option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /path/to/bitcoin-core
./bitcoin-qt -wallet&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;cold.dat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will load your cold wallet into your Bitcoin Core client. Once you’ve entered the passphrase, it’s good practice to consider the wallet “warmed-up” - so you could transfer any remaining funds to a new cold wallet.&lt;/p&gt;

&lt;p&gt;If you’re managing cold wallets like this, be very careful to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Encrypt wallets with a strong passphrase&lt;/li&gt;
  &lt;li&gt;Secure your passphrase and your wallet - there is &lt;strong&gt;NO&lt;/strong&gt; password reset option if you forget!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/How_to_set_up_a_secure_offline_savings_wallet&quot;&gt;Bitcoin Wiki: Setup secure offline savings wallet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tails.boum.org/install/debian/usb/index.en.html&quot;&gt;Detailed instructions on Tails installation&lt;/a&gt; in Linux Debian, Ubuntu and Mint&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitcoin.org/en/download&quot;&gt;Download Bitcoin Core&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/Cold_storage&quot;&gt;Bitcoin Wiki on Cold Storage&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitcoin.org/en/developer-reference#bitcoin-core-apis&quot;&gt;Bitcoin Core APIs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bitcoin/bitcoin/issues/9078#issuecomment-259259471&quot;&gt;Bitcoin Core GitHUb issue on Accounts&lt;/a&gt; discusses replacing account concept with simple labels&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/bitcoin-cold-wallet-setup&quot;&gt;Utility script to set up cold wallet for offline viewing&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://world.std.com/~reinhold/diceware.html&quot;&gt;Diceware&lt;/a&gt; - easier if you use gedit displaying line numbers for ease of lookup - do this offline if you’re paranoid!&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 18 Aug 2017 10:19:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/08/setup-and-manage-bitcoin-core-cold-storage-wallet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/08/setup-and-manage-bitcoin-core-cold-storage-wallet/</guid>
      </item>
      
    
      
      <item>
        <title>Open Encrypted Bitcoin Core Wallet</title>
        <description>&lt;p&gt;To decrypt a Bitcoin wallet in the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-cli&lt;/code&gt;, you need the &lt;code class=&quot;highlighter-rouge&quot;&gt;walletpassphrase&lt;/code&gt; command. This article shows how to avoid leaving the password in your shell history.&lt;/p&gt;

&lt;p&gt;These notes refer to Bitcoin core running on Ubuntu 16.04.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Silently read password&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -s PASSWORD
&lt;span class=&quot;c&quot;&gt;# Enter password&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Open the wallet for 60 seconds&lt;/span&gt;
./bitcoin-cli walletpassphrase &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; 60

&lt;span class=&quot;c&quot;&gt;# Do stuff - in this case, dump out a private key for a specified address&lt;/span&gt;
./bitcoin-cli dumpprivkey 12JZ2gDDRRLV9H5spbzygFok5VDd4jsWCV

&lt;span class=&quot;c&quot;&gt;# Lock Wallet when finished&lt;/span&gt;
./bitcoin-cli walletlock

&lt;span class=&quot;c&quot;&gt;# Empty the $PASSWORD variable&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Mon, 31 Jul 2017 21:41:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/open-encrypted-bitcoin-core-wallet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/open-encrypted-bitcoin-core-wallet/</guid>
      </item>
      
    
      
      <item>
        <title>Automatically Embed GitHub Gists in WordPress</title>
        <description>&lt;p&gt;To embed GitHub Gists in WordPress by simply pasting the Gist URL on a new line in the WordPress visual editor, register a handler on the &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_embed_register_handler&lt;/code&gt; hook.&lt;/p&gt;

&lt;h2 id=&quot;register-gists-for-oembed-functionality&quot;&gt;Register Gists for Oembed Functionality&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;wp_embed_register_handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'gist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#https?://gist.github.com/.*#i'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$url&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;nv&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$url&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;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;preg_match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#\.js$#i'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$url&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;nv&quot;&gt;$url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&amp;lt;script src=&quot;%s&quot;&amp;gt;&amp;lt;/script&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;esc_attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Mon, 31 Jul 2017 11:56:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/automatically-embed-github-gists-in-wordpress/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/automatically-embed-github-gists-in-wordpress/</guid>
      </item>
      
    
      
      <item>
        <title>Duplicate a Drive in Linux</title>
        <description>&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; command allows you to duplicate or clone drives exactly - the target will have the same permissions, formatting and media name.&lt;/p&gt;

&lt;p&gt;If the source drive is LUKS encrypted, the target drive will have exactly the same encryption state, and will be unlocked by the same passphrase as the original.&lt;/p&gt;

&lt;p&gt;I find this useful for making cloned copies of thumbdrives containing password databases.&lt;/p&gt;

&lt;h2 id=&quot;determine-paths&quot;&gt;Determine Paths&lt;/h2&gt;
&lt;p&gt;This can be achieved with the &lt;code class=&quot;highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;lsblk

&lt;span class=&quot;c&quot;&gt;# Typical output&lt;/span&gt;
NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0 465.8G  0 disk  
├─sda1                                          8:1    0   512M  0 part  /boot/efi
├─sda2                                          8:2    0   488M  0 part  /boot
└─sda3                                          8:3    0 464.8G  0 part  
  └─sda3_crypt                                252:0    0 464.8G  0 crypt
    ├─ubuntu--vg-root                         252:1    0 448.8G  0 lvm   /
    └─ubuntu--vg-swap_1                       252:2    0    16G  0 lvm   
      └─cryptswap1                            252:3    0    16G  0 crypt &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;SWAP]
sdb                                             8:16   0   1.8T  0 disk  
└─sdb1                                          8:17   0   1.8T  0 part  /media/datadrive
sdc                                             8:32   1   7.5G  0 disk  
└─sdc1                                          8:33   1   7.5G  0 part  
  └─luks-04235321-8ad9-4631-934c-2c09cfa700e7 252:4    0   7.5G  0 crypt /media/david/secure-data
sdd                                             8:48   1   7.5G  0 disk  
└─sdd1                                          8:49   1   7.5G  0 part  /media/david/Thumbdrive
loop0                                           7:0    0  80.5M  1 loop  /snap/core/2462
loop1                                           7:1    0  80.5M  1 loop  /snap/core/2381
loop2                                           7:2    0  79.5M  1 loop  /snap/core/2312
loop3                                           7:3    0 182.6M  1 loop  /snap/atom/9
loop4                                           7:4    0 182.6M  1 loop  /snap/atom/8&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdc&lt;/code&gt; is the source (or ‘input file’ in &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; parlance) and &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sdd&lt;/code&gt; is the target (or ‘output file’).&lt;/p&gt;

&lt;h2 id=&quot;clone-drives&quot;&gt;Clone Drives&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Make sure you correctly identify the drives&lt;/strong&gt; - especially the output/target, since &lt;code class=&quot;highlighter-rouge&quot;&gt;dd&lt;/code&gt; will overwrite all data. In this case, we can easily identify the pair of thumbdrives based on their size.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;## Clone sdc to sdd&lt;/span&gt;
sudo dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdc &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdd&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When finished, the new drive will be an exact copy - with the same identifier. As such, it won’t be possible to mount the original and the clone at the same time.&lt;/p&gt;

&lt;p&gt;Because of this, if you want to repeat the process you may need to temporarily change the passphrase on the target drive, or wipe it altogether. To wipe the drive:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdd&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki//dev/zero&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/zero&lt;/code&gt;&lt;/a&gt; - provide null characters&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.beginninglinux.com/home/backup/backup-or-clone-usb-key-drive---encrypted&quot;&gt;Cloning an encrypted drive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 28 Jul 2017 14:25:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/duplicate-a-drive-linux/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/duplicate-a-drive-linux/</guid>
      </item>
      
    
      
      <item>
        <title>Ignore IP Addresses in Fail2Ban</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://www.fail2ban.org/wiki/index.php/Main_Page&quot;&gt;Fail2Ban&lt;/a&gt; can help protect your Linux server from attack. It’s a Python package that monitors log files and dynamically adjusts firewall rules to block malicious IP addresses.&lt;/p&gt;

&lt;p&gt;You can set (or use pre-configured) Python regexes - in Fail2Ban parlance, ‘filters’ - to determine malicious requests. If Fail2Ban detects a particular frequency of the filter regex in a specified log file, an iptables rule is dynamically generated that bans the abusive IP address for a set period of time.&lt;/p&gt;

&lt;h2 id=&quot;fail2ban-config&quot;&gt;Fail2Ban Config&lt;/h2&gt;
&lt;p&gt;Fail2Ban can be configured with actions that determine the exact behaviour for a given ‘jail’. In this way, responses to particular actions can be fine-tuned. For example, you could configure Fail2Ban to trigger a ban for the originating IP address:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;After 3 failed SSH login attempts over a 10 minute period&lt;/li&gt;
  &lt;li&gt;After a single attempt at user-enumeration - in the context of WordPress, this type of request is almost certainly malicious&lt;/li&gt;
  &lt;li&gt;After 6 failed submissions over a five minute period on a public-facing user login form&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Ubuntu 16.04, the main configuration file is &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt;. You should not edit this, as your customisations will be over-written on upgrade. Instead, extend the configuration by either:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Adding override rules to a &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.local&lt;/code&gt; file&lt;/li&gt;
  &lt;li&gt;Adding config rules on a file-by-file basis in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.d&lt;/code&gt; directory, with the &lt;code class=&quot;highlighter-rouge&quot;&gt;.conf&lt;/code&gt; suffix&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The config files should reference filters - which determine the target regexes. There are a wide range of pre-configured regexes available here: &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/filter.d&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;override-ip-addresses&quot;&gt;Override IP Addresses&lt;/h2&gt;
&lt;p&gt;Fail2Ban allows you to list IP addresses which should be ignored. This can be useful for testing purposes, and can help avoid locking clients (or yourself) out unecessarily.&lt;/p&gt;

&lt;p&gt;To achieve this, just add &lt;code class=&quot;highlighter-rouge&quot;&gt;ignoreip = 127.0.0.1/8 x.x.x.x y.y.y.y&lt;/code&gt; to the relevant action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note that if you add a specific IP address to an action, it will override the default value.&lt;/strong&gt;
The child action overwrites the ignoreip rule - it does not merge IP addresses.&lt;/p&gt;

&lt;h2 id=&quot;example-jaillocal&quot;&gt;Example jail.local&lt;/h2&gt;
&lt;p&gt;The code below defines actions in a single file. You don’t need to copy across the entire &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt; file - just extend the necessary sections.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# File: /etc/fail2ban/jail.local&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Fail2ban overrides&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# These rules override `/etc/fail2ban/jail.conf`.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# =============================================================&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;DEFAULT]
&lt;span class=&quot;c&quot;&gt;# Ban bad hosts for one hour:&lt;/span&gt;
bantime &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 3600
&lt;span class=&quot;c&quot;&gt;# Override /etc/fail2ban/jail.d/00-firewalld.conf:&lt;/span&gt;
banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-multiport
&lt;span class=&quot;c&quot;&gt;# Emails&lt;/span&gt;
destemail &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; serveradmin@example.com
sendername &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; Fail2Ban_Archimedes
mta &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; mail
&lt;span class=&quot;c&quot;&gt;# Action&lt;/span&gt;
action &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;action_mwl&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
&lt;span class=&quot;c&quot;&gt;# List of safe IP addresses&lt;/span&gt;
ignoreip &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127.0.0.1/8 x.x.x.x

&lt;span class=&quot;c&quot;&gt;# ============================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Jails Enabled&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ============================================================&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# sshd jail is already enabled by default, so this isn't strictly necessary&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sshd]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 36000
&lt;span class=&quot;c&quot;&gt;# Override the default value - overwrites, does not merge&lt;/span&gt;
ignoreip &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127.0.0.1/8 x.x.x.x y.y.y.y

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ssh]
enabled  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 9999
&lt;span class=&quot;c&quot;&gt;# Use a pre-configured filter&lt;/span&gt;
filter   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; sshd
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 36000
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/auth.log
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6
ignoreip &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127.0.0.1/8 x.x.x.x y.y.y.y

&lt;span class=&quot;c&quot;&gt;# For WordPress jails, you need to configure WordPress to write to the specified log.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You also need to create appropriate filters e.g. `/etc/fail2ban/filter.d/wordpress-hard.conf`.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# This jails IP addresses that are certainly malicious (e.g. trying to enumerate users)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;wordpress-hard]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;filter &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; wordpress-hard
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 36000
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/auth.log
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https

&lt;span class=&quot;c&quot;&gt;# Softer jail - allows users to retry their logins&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;wordpress-soft]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;filter &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; wordpress-soft
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 36000
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/auth.log
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 3
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.fail2ban.org/wiki/index.php/Main_Page&quot;&gt;Fail2Ban&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 20 Jul 2017 10:29:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/ignore-ip-addresses-in-fail2ban/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/ignore-ip-addresses-in-fail2ban/</guid>
      </item>
      
    
      
      <item>
        <title>Declaring Variables in Ecmascript 6</title>
        <description>&lt;p&gt;Variables are used as symbolic names for values. Variable names are known as ‘identifiers’. In JavaScript, identifiers are case-sensitive and must begin with a letter, underscore or dollar sign.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;Don’t use &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt; to declare variables - use &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; where possible and &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; otherwise. Use a transpiler like &lt;a href=&quot;https://babeljs.io/&quot;&gt;babel&lt;/a&gt; to sort things out for pre-ES6 browsers.&lt;/p&gt;

&lt;h2 id=&quot;variable-declaration&quot;&gt;Variable Declaration&lt;/h2&gt;
&lt;p&gt;Ecmascript 6 introduced the &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; statements for declaring variables. This means that variables can be declared as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt;: Declare a variable, optionally assigning a value&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;: Declare a block-scoped local variable, optionally assigning a value&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt;: Declare a block-scoped read-only constant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Declarations&quot;&gt;Source: MDN JavaScript Guide&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;scoping&quot;&gt;Scoping&lt;/h2&gt;
&lt;p&gt;Variables defined with &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; are function scoped, whereas variables defined with &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; are block-scoped.&lt;/p&gt;

&lt;p&gt;Block scoping basically means that the variable scope is limited by the enclosing &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;&lt;/code&gt; - so a variable is declared by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; is limited in it’s scope to the block, statement or expression in which it is used.&lt;/p&gt;

&lt;p&gt;This can be useful when dealing with loop iterations - when the counter variable is defined by &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt;, all loop iterations (confusingly) share the same &lt;em&gt;function-scoped&lt;/em&gt; counter variable, leading to unexpected results. Declaring the index with &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; produces a much more intuitive result:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Declare iterator with let&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'use strict'&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&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;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&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;c1&quot;&gt;// returns Array [ 0, 1, 2, 3, 4 ]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Declare iterator with var&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// -----------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'use strict'&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&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;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&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;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&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;c1&quot;&gt;// returns Array [ 5, 5, 5, 5, 5 ]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Source: &lt;a href=&quot;https://softwareengineering.stackexchange.com/a/274352/278079&quot;&gt;SE answer&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;const&quot;&gt;const&lt;/h2&gt;
&lt;p&gt;This is another way to declare variables - like &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;, variables &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt; has block scope. Variables declared in this way are read-only &lt;strong&gt;constants&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can’t change the value of a constant by re-assignment, and it can’t be re-declared. However, the value held by a constant is not immutable. If you define an object using &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt;, the object contents can be amended.&lt;/p&gt;

&lt;p&gt;A constant can’t have the same name as a function or variable in the same scope. Constants can be declared with uppercase or lowercase letters - a common convention is to use all-uppercase letters.&lt;/p&gt;

&lt;p&gt;A constant can have global scope (i.e. on the window object) if defined outside a block.&lt;/p&gt;

&lt;p&gt;If you don’t need to change a variable, it’s probably a good idea to use &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt;. This helps to &lt;strong&gt;Minimize Mutable State&lt;/strong&gt; - Mutable state makes mistakes more likely.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://softwareengineering.stackexchange.com/a/274352/278079&quot;&gt;SE answer&lt;/a&gt; with a good description of why &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt; is better than &lt;code class=&quot;highlighter-rouge&quot;&gt;var&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/Ji6NHEnNHcA?t=26m9s&quot;&gt;Douglas Crockford discussing the issue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=sjyJBL5fkp8&quot;&gt;Useful YouTube video from funfunfunction&lt;/a&gt; - as well as being really useful, this guy is very entertaining!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const&quot;&gt;MDN on &lt;code class=&quot;highlighter-rouge&quot;&gt;const&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Block_scope_with_let&quot;&gt;MDN on &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 15 Jul 2017 20:30:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/ecmascript-6-statements-and-declarations/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/ecmascript-6-statements-and-declarations/</guid>
      </item>
      
    
      
      <item>
        <title>Reorganise Letsencrypt Certificates</title>
        <description>&lt;p&gt;This article refers to a Letsencrypt client as installed by &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install python-letsencrypt-apache&lt;/code&gt;. Up until quite recently, this was the recommended Letsencrypt installation for Ubuntu Xenial 16.04.&lt;/p&gt;

&lt;h2 id=&quot;insurance-make-a-backup&quot;&gt;Insurance: Make a Backup!&lt;/h2&gt;
&lt;p&gt;Backup the entire &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt&lt;/code&gt; directory - recursively copy the entire &lt;code class=&quot;highlighter-rouge&quot;&gt;letsencrypt&lt;/code&gt; directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cp /etc/letsencrypt/ /etc/letsencrypt.backup -r&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you mess up during the process of certificate reorganisation, revert to the original and save the broken state for reference:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Recover from broken state&lt;/span&gt;
mv /etc/letsencrypt /etc/letsencrypt.broken &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; mv /etc/letsencrypt.backup/ /etc/letsencrypt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;certificate-lineage&quot;&gt;Certificate Lineage&lt;/h2&gt;
&lt;p&gt;Determine certificate lineages by listing out the domains associated with each certificate - look in subdirectories under &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt/live&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout | grep DNS
openssl x509 -in /etc/letsencrypt/live/www.example.com/cert.pem -text -noout | grep DNS&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See &lt;a href=&quot;#additional-information&quot;&gt;additional information&lt;/a&gt; for a breakdown of this command.&lt;/p&gt;

&lt;h2 id=&quot;remove-a-superfluous-certificate&quot;&gt;Remove a Superfluous Certificate&lt;/h2&gt;
&lt;p&gt;We determine that the example.com cert is superfluous, and holds references to invalid domains. The cert is not being used, but generates ugly error messages during the renewal dry-run.&lt;/p&gt;

&lt;p&gt;Be careful - make sure the cert is not being referenced in any Virtual Host directives.&lt;/p&gt;

&lt;p&gt;If you are sure it’s safe, remove it and run the renewal process:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rm -rf /etc/letsencrypt/live/example.com/
rm -rf /etc/letsencrypt/archive/example.com
rm /etc/letsencrypt/renewal/example.com.conf

&lt;span class=&quot;c&quot;&gt;# Attempt a dry-run renewal first if necessary&lt;/span&gt;
sudo letsencrypt renew --dry-run --agree-tos

&lt;span class=&quot;c&quot;&gt;# Run the renewal&lt;/span&gt;
sudo letsencrypt renew&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;reissue-certificate&quot;&gt;Reissue Certificate&lt;/h2&gt;
&lt;p&gt;I haven’t attempted this - but running the following should install a new certificate:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# CAUTION: Not tested&lt;/span&gt;
sudo letsencrypt certonly --webroot-path /var/www/html -d example.com -d www.example.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If your virtual hosts for the specified domains are referencing certs like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;SSLCertificateFile&lt;/span&gt; /etc/letsencrypt/live/example.com/fullchain.pem
&lt;span class=&quot;nc&quot;&gt;SSLCertificateKeyFile&lt;/span&gt; /etc/letsencrypt/live/example.com/privkey.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…the new cert should work.&lt;/p&gt;

&lt;h2 id=&quot;additional-information&quot;&gt;Additional Information&lt;/h2&gt;
&lt;p&gt;OpenSSL is an open source toolkit for the SSL and TLS network protocols and related cryptography standards, accessed with the - &lt;code class=&quot;highlighter-rouge&quot;&gt;openssl&lt;/code&gt; utility. The &lt;code class=&quot;highlighter-rouge&quot;&gt;x509&lt;/code&gt; command provides utilities for displaying, converting and signing certificates. Summary of the above command:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-in filename&lt;/code&gt;: the input filename to read from (standard input if not specified)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-text&lt;/code&gt;: print the certificate in text form&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-noout&lt;/code&gt;: prevent output of the encoded version of the request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The text form output includes full details - public key, signature algorithms, issuer &amp;amp; subject names, serial number, extensions present, any trust settings and the DNS records covered by the certificate. In the context of this article, we’re only interested in the certificate lineage/associated domains - so the &lt;code class=&quot;highlighter-rouge&quot;&gt;openssl x509&lt;/code&gt; command is piped to &lt;code class=&quot;highlighter-rouge&quot;&gt;grep DNS&lt;/code&gt; to output the DNS data only.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;This article is largely based on the &lt;a href=&quot;https://community.letsencrypt.org/t/remove-domain-not-required-from-cert/14010/6?u=davidcwebs&quot;&gt;very useful answer on Letsencrypt discourse&lt;/a&gt; by &lt;a href=&quot;https://community.letsencrypt.org/u/pfg/summary&quot;&gt;pfg&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.openssl.org/docs/manmaster/man1/x509.html&quot;&gt;openssl x509 man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 13 Jul 2017 11:26:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/reorganise-letsencrypt-certificates-remove-cert/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/reorganise-letsencrypt-certificates-remove-cert/</guid>
      </item>
      
    
      
      <item>
        <title>Setup New Vue Webpack Project With Bulma</title>
        <description>&lt;p&gt;How to set up a new Vue project with Webpack and Bulma using the Vue CLI.&lt;/p&gt;

&lt;h2 id=&quot;vue-cli&quot;&gt;Vue CLI&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vuejs/vue-cli&quot;&gt;Vue CLI&lt;/a&gt; is a simple yet powerful CLI that you can use to scaffold Vue projects.&lt;/p&gt;

&lt;p&gt;Install Vue CLI Globally:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Using Yarn&lt;/span&gt;
yarn global add vue-cli

&lt;span class=&quot;c&quot;&gt;# Using NPM&lt;/span&gt;
npm install -g vue-cli&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now use the Vue CLI to scaffold projects. There are a number of templates available, but this article focuses on Webpack.&lt;/p&gt;

&lt;h2 id=&quot;scaffold-a-project&quot;&gt;Scaffold a Project&lt;/h2&gt;
&lt;p&gt;To scaffold a Vue project with the Webpack template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Move into a suitable location&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/html

&lt;span class=&quot;c&quot;&gt;# Scaffold a Vue/Webpack project into /var/www/html/new-project.dev&lt;/span&gt;
vue init webpack new-project.dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-dependencies&quot;&gt;Install Dependencies&lt;/h2&gt;
&lt;p&gt;Move into the new project directory and install the base dependencies:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Using yarn:&lt;/span&gt;
yarn install

&lt;span class=&quot;c&quot;&gt;# Using NPM:&lt;/span&gt;
npm install&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;add-dependencies&quot;&gt;Add Dependencies&lt;/h2&gt;
&lt;p&gt;Add Bulma:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Using Yarn&lt;/span&gt;
yarn add bulma

&lt;span class=&quot;c&quot;&gt;# Using NPM:&lt;/span&gt;
npm install bulma

&lt;span class=&quot;c&quot;&gt;# To add multiple packages with Yarn, separate with a space. e.g.:&lt;/span&gt;
yarn add axios bulma&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;run-dev-server&quot;&gt;Run Dev server&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Using Yarn&lt;/span&gt;
yarn dev

&lt;span class=&quot;c&quot;&gt;# Using NPM&lt;/span&gt;
npm run dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;connect-up-bulma&quot;&gt;Connect Up Bulma&lt;/h2&gt;
&lt;p&gt;Add a suitable SASS manifest file that you’ll use to import all your SASS modules:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# From project root:&lt;/span&gt;
touch src/assets/sass/main.scss&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Open this file and import the main Bulma Sass file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sass&quot; data-lang=&quot;sass&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/assets/sass/main.scss
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'~bulma/bulma'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the tilde symbol refers Webpack/sass-loader to the &lt;code class=&quot;highlighter-rouge&quot;&gt;node_modules&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;You then need to reference this in Webpack’s main entry point, &lt;code class=&quot;highlighter-rouge&quot;&gt;src/main.js&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/main.js&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'vue'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'./App'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'./router'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Require the main Sass manifest file&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./assets/sass/main.scss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;productionTip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/* eslint-disable no-new */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#app'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;App/&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;components&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;nx&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;bulma-sass---additional-dependencies&quot;&gt;Bulma Sass - Additional Dependencies&lt;/h2&gt;
&lt;p&gt;Note that to compile Sass, Webpack needs the &lt;code class=&quot;highlighter-rouge&quot;&gt;node-sass&lt;/code&gt; node module and the Webpack &lt;code class=&quot;highlighter-rouge&quot;&gt;sass-loader&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;Add these to your project dependencies:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yarn add node-sass sass-loader&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now run &lt;code class=&quot;highlighter-rouge&quot;&gt;yarn dev&lt;/code&gt; to build your development server.&lt;/p&gt;

&lt;h2 id=&quot;problem-with-ubuntu-snap-installed-atom-code-editor-and-webpack-server&quot;&gt;Problem With Ubuntu Snap-Installed Atom (code editor) and Webpack Server&lt;/h2&gt;
&lt;p&gt;You may experience problems because &lt;code class=&quot;highlighter-rouge&quot;&gt;xdg-open&lt;/code&gt; does not run properly when launched within Atom (i.e. in platformio-ide-terminal) when Atom has been installed by means of a Ubuntu snap. This is because there is a GTK+ 2.x and GTK+ 3 conflict.&lt;/p&gt;

&lt;p&gt;To resolve this, you can manually specify the browser to be used when the Webpack server is triggered. Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;build/dev-server.js&lt;/code&gt; by passing in a preferred browser as a second parameter into the call to &lt;a href=&quot;https://github.com/sindresorhus/opn&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;node-opn&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;devMiddleware&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;waitUntilValid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&amp;gt; Listening at '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\n'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// when env is testing, don't need open it&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;autoOpenBrowser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NODE_ENV&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'testing'&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;c1&quot;&gt;// Set the browser here!&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;opn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uri&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;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'firefox-developer'&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;nx&quot;&gt;_resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 11 Jul 2017 20:10:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/setup-new-vue-webpack-project-with-bulma/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/setup-new-vue-webpack-project-with-bulma/</guid>
      </item>
      
    
      
      <item>
        <title>Install and Run Geth (golang implemenation of Ethereum) on Ubuntu</title>
        <description>&lt;p&gt;Ethereum is a decentralized blockchain-based platform that runs smart contracts. Because of the decentralized nature of Ethereum, smart contracts run exactly as programmed - short of an internet apocalypse, there is no possibility of downtime, censorship, fraud or third-party interference. The network is cryptographically secure, decentralized and tamper-proof.&lt;/p&gt;

&lt;p&gt;The ethereum network is “fuelled” by Ether. Clients of the platform pay Ether to the machines carrying out the requested computations. In this way, people are compensated for contributing resources and developers are incentivized to write efficient applications.&lt;/p&gt;

&lt;p&gt;It’s a bit tricky to get started with Ethereum - there are numerous confusing articles floating about the internet. This article is intended to be a very basic guide to getting started with the golang implementation of Ethereum - &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt;, a command line tool. The article covers installing the package, setting up accounts and syncing the Ethereum blockchain. For a curated list of useful resources, see the &lt;a href=&quot;#references&quot;&gt;References&lt;/a&gt; section.&lt;/p&gt;

&lt;h2 id=&quot;go-ethereum-geth&quot;&gt;Go Ethereum: Geth&lt;/h2&gt;
&lt;p&gt;Go Ethereum (&lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt;) is the official golang implementation of the Ethereum protocol. It is one of the three original implementations (the others being C++ and Python) of the Ethereum protocol. The package is fully open source and licensed under the GNU LGPL v3.&lt;/p&gt;

&lt;p&gt;Geth is basically a command line interface (CLI) for running a full ethereum node. As well as being a CLI, &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; can be associated with a JavaScript console&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;Install go-ethereum on Ubuntu:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that this installs a suite of Ethereum utilities as well as &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bootnode&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;evm&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;disasm&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rlpdump&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ethtest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you just want to install geth, run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install geth&lt;/code&gt; rather than &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install ethereum&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;initial-setup-create-account&quot;&gt;Initial Setup: Create Account&lt;/h2&gt;
&lt;p&gt;Show geth options:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;geth --help&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set up an account:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set up account - enter a strong passphrase&lt;/span&gt;
geth account new

&lt;span class=&quot;c&quot;&gt;# Check that accoun&lt;/span&gt;
geth account list&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;a-note-on-passwords-and-security&quot;&gt;A Note on Passwords and Security&lt;/h2&gt;
&lt;p&gt;If you forget your account password/passphrase, you lose all access to that account - and any funds that it holds. There is no password reset! Notwithstanding this, you should set a strong passphrase for the sake of good security.&lt;/p&gt;

&lt;p&gt;KeePassX is available for Ubuntu - it is a password storage tool that constitutes an encrypted database. I strongly recommend using such a tool - you just need to remember one strong passphrase to unlock your KeePassX database. This will allow you to save extremely strong passwords for your Ethereum accounts, since you’ll never have to remember them.&lt;/p&gt;

&lt;h2 id=&quot;initial-setup-sync-the-ethereum-blockchain&quot;&gt;Initial Setup: Sync the Ethereum Blockchain&lt;/h2&gt;
&lt;p&gt;The best option is to run &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; with the fast sync option - this spares bandwidth usage, though it requires extra processing power. Fast sync downloads transaction receipts rather than the entire blockchain for historical records, and pulls an entire recent state database. See this &lt;a href=&quot;https://github.com/ethereum/go-ethereum/pull/1889&quot;&gt;PR comment&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;To fast sync with a 2GB memory cache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;geth --fast --cache&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2048&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This builds the ethereum blockchain in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.ethereum/geth/chaindata&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you have synced the blockchain on one trusted computer, you can export this and import to a second machine. I tried this - it was taking so long that I aborted and opted for the fast-sync method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As of 3 July 2017 the chaindata directory is 29 GB&lt;/strong&gt;. If you have a bandwidth cap, you could run the sync during unrestricted time-periods by means of a crontab script.&lt;/p&gt;

&lt;h2 id=&quot;running-geth-to-stay-in-sync&quot;&gt;Running Geth to Stay in Sync&lt;/h2&gt;
&lt;p&gt;Once you have fast-synced, you need to run &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; periodically to keep up-to-date with the ethereum blockchain.&lt;/p&gt;

&lt;h2 id=&quot;javascript-console&quot;&gt;JavaScript Console&lt;/h2&gt;
&lt;p&gt;You can launch &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; with the &lt;code class=&quot;highlighter-rouge&quot;&gt;console&lt;/code&gt; option to provide an interactive JavaScript console. Alternatively, launch &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; and run &lt;code class=&quot;highlighter-rouge&quot;&gt;geth attach&lt;/code&gt; in another terminal. The latter method is convenient as you’ll be less distracted by logging output.&lt;/p&gt;

&lt;p&gt;This example shows how you might monitor progress in an attached console:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Assuming geth is running in a separate terminal...this will open a Javcascript console&lt;/span&gt;
geth attach&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The JavaScript console:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Check if syncing&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;eth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;syncing&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Get the current block number&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;eth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;blockNumber&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Return the number of peers connected&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;peerCount&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Exit this console&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exit&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;clean-exit-of-geth&quot;&gt;Clean Exit of Geth&lt;/h2&gt;
&lt;p&gt;You can shut down &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;CTRL-C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you have attached a JavaScript console to a running &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; instance, this won’t work. You need to first exit the JavaScript console - you can do this cleanly by entering &lt;code class=&quot;highlighter-rouge&quot;&gt;exit&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;CTRL-C&lt;/code&gt; in the JS console first, before closing the original &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; instance by entering &lt;code class=&quot;highlighter-rouge&quot;&gt;CTRL-C&lt;/code&gt; in the relevant terminal.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://geth.ethereum.org/&quot;&gt;Go ethereum home page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://geth.ethereum.org/install/#install-on-ubuntu-via-ppas&quot;&gt;Install Go Ethereum on Ubuntu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://launchpad.net/~ethereum/+archive/ubuntu/ethereum&quot;&gt;Ethereum PPA on Launchpad&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ethereum.org/cli&quot;&gt;Ethereum CLI guide for developers&lt;/a&gt; - with info on &lt;code class=&quot;highlighter-rouge&quot;&gt;geth&lt;/code&gt; usage&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ethereum/go-ethereum&quot;&gt;Go-ethereum Github repo&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ethereum/go-ethereum/wiki/geth&quot;&gt;Wiki for golang Ethereum implementation (geth)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ethereum.gitbooks.io/frontier-guide/content/&quot;&gt;Go-ethereum User Guide &amp;amp; Reference Manual(Frontier)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://geth.ethereum.org/downloads/&quot;&gt;Alternative Installation: Go Ethereum Package Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 03 Jul 2017 10:48:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/install-and-run-ethereum-geth-on-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/install-and-run-ethereum-geth-on-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Verification of Bitcoin Core Download in Ubuntu</title>
        <description>&lt;p&gt;There are numerous ways to install Bitcoin Core in Ubuntu:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;via &lt;a href=&quot;https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin&quot;&gt;PPA&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Cloning from Github&lt;/li&gt;
  &lt;li&gt;Downloading the binaries from &lt;a href=&quot;https://bitcoin.org/en/download&quot;&gt;https://bitcoin.org/en/download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install-via-downloaded-package-from-bitcoinorg&quot;&gt;Install Via Downloaded Package from bitcoin.org&lt;/h2&gt;
&lt;p&gt;Download Bitcoin Core:
&lt;a href=&quot;https://bitcoin.org/en/download&quot;&gt;https://bitcoin.org/en/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select Linux (tgz), which will trigger a download - at the time of writing: &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-0.14.2-x86_64-linux-gnu.tar.gz&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;verification&quot;&gt;Verification&lt;/h3&gt;
&lt;p&gt;Download the release signature document. At the time of writing, this is here: &lt;a href=&quot;https://bitcoin.org/bin/bitcoin-core-0.14.2/SHA256SUMS.asc&quot;&gt;https://bitcoin.org/bin/bitcoin-core-0.14.2/SHA256SUMS.asc&lt;/a&gt;. This downloads &lt;code class=&quot;highlighter-rouge&quot;&gt;SHA256SUMS.asc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This file is a signed PGP message that contains the SHA256 sums for the various Bitcoin core downloads. By comparing the relevant value with the SHA256 sum of the &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoin-0.14.2-x86_64-linux-gnu.tar.gz&lt;/code&gt; that you have downloaded, you can verify the authenticity of what you have downloaded.&lt;/p&gt;

&lt;p&gt;You should first verify that the signature document itself is authentic. This is done using &lt;a href=&quot;https://www.gnupg.org&quot;&gt;Gnu Privacy Guard (GPG)&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;verification-of-the-signatures-document&quot;&gt;Verification of the Signatures Document&lt;/h3&gt;
&lt;p&gt;Download the relevant GPG signing key - these are presented on the &lt;a href=&quot;(https://bitcoin.org/en/download)&quot;&gt;download page&lt;/a&gt; under the title “Bitcoin Core Release Signing Keys”. Click the correct version to download the relevant key. At the time of writing, this is &lt;code class=&quot;highlighter-rouge&quot;&gt;laanwj-releases.asc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your &lt;code class=&quot;highlighter-rouge&quot;&gt;~/Downloads&lt;/code&gt; directory should now contain:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;david@desktop:~/Downloads$ &lt;/span&gt;ls -la
total 24164
drwxr-xr-x  2 david david     4096 Jun 29 19:27 .
drwx------ 47 david david    12288 Jun 29 19:14 ..
-rw-rw-r--  1 david david 24607581 Jun 29 18:21 bitcoin-0.14.2-x86_64-linux-gnu.tar.gz
-rw-rw-r--  1 david david    17940 Jun 29 18:57 laanwj-releases.asc
-rw-rw-r--  1 david david     1957 Jun 29 18:55 SHA256SUMS.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;import-the-public-key&quot;&gt;Import the Public Key&lt;/h3&gt;
&lt;p&gt;Move into your &lt;code class=&quot;highlighter-rouge&quot;&gt;~/Downloads&lt;/code&gt; directory and run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpg --import laanwj-releases.asc
gpg: /home/david/.gnupg/trustdb.gpg: trustdb created
gpg: key 36C2E964: public key &lt;span class=&quot;s2&quot;&gt;&quot;Sender Name (Bitcoin Core binary release signing key) &amp;lt;sender@example.com&amp;gt;&quot;&lt;/span&gt; imported
gpg: Total number processed: 1
gpg:               imported: 1  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;RSA: 1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
gpg: no ultimately trusted keys found

&lt;span class=&quot;c&quot;&gt;# Verify that key was imported:&lt;/span&gt;
gpg --list-keys
/home/david/.gnupg/pubring.gpg
------------------------------
pub   4096R/36C2E964 2015-06-24 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;expires: 2019-02-14]
uid                  Sender Name &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Bitcoin Core binary release signing key&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt;sender@example.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;check-signatures-document&quot;&gt;Check Signatures Document&lt;/h3&gt;
&lt;p&gt;You can now establish the authenticity of the signatures document by running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpg --verify SHA256SUMS.asc
gpg: Signature made Sat 17 Jun 2017 11:33:26 IST using RSA key ID 36C2E964
gpg: Good signature from &lt;span class=&quot;s2&quot;&gt;&quot;Sender Name (Bitcoin Core binary release signing key) &amp;lt;sender@example.com&amp;gt;&quot;&lt;/span&gt;
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: ...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;check-the-authenticity-of-the-download-sha256-checksum&quot;&gt;Check the Authenticity of the Download: SHA256 Checksum&lt;/h3&gt;
&lt;p&gt;You can now use the signatures document to establish the authenticity of the Bitcoin download.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/Downloads

sha256sum -c SHA256SUMS.asc 2&amp;gt;&amp;amp;1 | grep OK

&lt;span class=&quot;c&quot;&gt;# If all is OK, this will be the result:&lt;/span&gt;
bitcoin-0.14.2-x86_64-linux-gnu.tar.gz: OK&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the tar.gz file provided for download doesn’t appear to contain source files (as suggested &lt;a href=&quot;https://en.bitcoin.it/wiki/Using_Bitcoin#Download_and_install_the_client&quot;&gt;here&lt;/a&gt;), so you can’t use this to compile. It does include binaries.&lt;/p&gt;

&lt;h2 id=&quot;install-via-github&quot;&gt;Install Via Github&lt;/h2&gt;
&lt;p&gt;You can clone Bitcoin source code from Github, and compile from this.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~
git clone https://github.com/bitcoin/bitcoin.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are quite a few dependencies - these are outlined in the &lt;code class=&quot;highlighter-rouge&quot;&gt;doc/build-unix.md&lt;/code&gt; document: &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md&quot;&gt;https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Installing from GitHub is probably a pretty secure method as you’ll be pulling the files over an encrypted connection - so long as you trust that the Github repo has not been tampered with (which makes Github probably as trusted an installation route as the downloadable binaries).&lt;/p&gt;

&lt;h2 id=&quot;install-via-ppa&quot;&gt;Install Via PPA&lt;/h2&gt;
&lt;p&gt;To install via PPA, add &lt;code class=&quot;highlighter-rouge&quot;&gt;ppa:bitcoin/bitcoin&lt;/code&gt; to your system’s Software Sources:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo add-apt-repository ppa:bitcoin/bitcoin
sudo apt-get update&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is the stable Channel of bitcoin-qt (GUI) and bitcoind (CLI) for Ubuntu. The Launchpad description actually recommends use of the official binaries, where possible, to limit trust in Launchpad/the PPA owner.&lt;/p&gt;

&lt;h2 id=&quot;running-bitcoin&quot;&gt;Running Bitcoin&lt;/h2&gt;
&lt;p&gt;Once you have verified your download, move the downloaded file into a suitable location where the binaries can be run.
The downloaded file is a zipped directory so it should be OK to unzip in situ:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;tar -zvxf bitcoin-0.16.0-x86_64-linux-gnu.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The binaries are located in the &lt;code class=&quot;highlighter-rouge&quot;&gt;bin&lt;/code&gt; directory. To run bitcoin-qt, move into bin and run &lt;code class=&quot;highlighter-rouge&quot;&gt;./bin/bitcoin-qt&lt;/code&gt;. The first time you run this, the programme will build the default data directory for you.&lt;/p&gt;

&lt;p&gt;It is more convenient to create a symlink to the executables (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;bin/bitcoin-qt&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;bin/bitcoind&lt;/code&gt;) in &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt;. You can then easily start Bitcoin executables from the command line.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TLDR&lt;/h2&gt;
&lt;p&gt;Download core:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;c&quot;&gt;# NB: check version&lt;/span&gt;
wget https://bitcoincore.org/bin/bitcoin-core-0.16.0/bitcoin-0.16.0-x86_64-linux-gnu.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Download signatures:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;wget https://bitcoincore.org/bin/bitcoin-core-0.16.0/SHA256SUMS.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check signatures doc:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;gpg --verify SHA256SUMS.asc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Verify the signing key e.g.: https://github.com/bitcoin/bitcoin/tree/master/contrib/verifybinaries.
Verify the shasum for the download:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;sha256sum -c SHA256SUMS.asc 2&amp;gt;&amp;amp;1 | grep OK&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If all is OK, this will be the result:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;bitcoin-0.16.0-x86_64-linux-gnu.tar.gz: OK&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Move the download and unzip:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;tar -zvxf bitcoin-0.16.0-x86_64-linux-gnu.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/Bitcoin/wiki/verifying_bitcoin_core&quot;&gt;Verify Bitcoin Core&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/HowToSHA256SUM&quot;&gt;SHA256SUM on Linux&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Step_by_Step_Guide/s1-gnupg-import.html&quot;&gt;Inporting GPG Public Keys&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/Using_Bitcoin#Download_and_install_the_client&quot;&gt;Downloading Bitcoin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 01 Jul 2017 10:09:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/07/verification-of-bitcoin-core-download-in-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/07/verification-of-bitcoin-core-download-in-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Enable all Apache Config Files</title>
        <description>&lt;p&gt;Use this BASH script to quickly enable all Apache virtual host configurations.&lt;/p&gt;

&lt;p&gt;THis can be handy if for example you are setting up a new development environment.&lt;/p&gt;

&lt;h2 id=&quot;background-enabling-virtual-hosts-in-apache-24&quot;&gt;Background: Enabling Virtual Hosts in Apache 2.4&lt;/h2&gt;
&lt;p&gt;To set up Apache 2.4 virtual host configurations under Debian/Ubuntu you add a configuration file with a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;VirtualHost&amp;gt;&lt;/code&gt; block in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Such config files must have the &lt;code class=&quot;highlighter-rouge&quot;&gt;.conf&lt;/code&gt; file extension.&lt;/p&gt;

&lt;p&gt;To enable the site, you need to run the &lt;code class=&quot;highlighter-rouge&quot;&gt;a2ensite&lt;/code&gt; script, passing the config filename as an argument. This creates a symlink to the config file in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-enabled&lt;/code&gt; directory. You then need to reload Apache.&lt;/p&gt;

&lt;h2 id=&quot;script&quot;&gt;Script&lt;/h2&gt;
&lt;p&gt;The following script loops through all config files in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; and runs &lt;code class=&quot;highlighter-rouge&quot;&gt;a2ensite&lt;/code&gt;. There’s no problem if any site is already enabled, since this does not result in an error.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Enable all config files in /etc/apache2/sites-available directory.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Usage: Make this script executable and run as a user with sudo privileges.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;BASE_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/sites-available&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;FILEPATH &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$BASE_DIR&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;do
  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; -f &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FILEPATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONF&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FILEPATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
    a2ensite &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONF&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; !&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;then
      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;a2ensite NOT successful for &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONF&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else
      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;a2ensite successful for &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CONF&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi
  fi
done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Reload apache&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you want to reload Apache (y/n)?&quot;&lt;/span&gt; CONT
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CONT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;y&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;service apache2 reload
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -eq 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;then
      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Apache reloaded - check sites in browser.&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else
      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;There was a problem reloading Apache.&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi
else
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Changes won't take effect until Apache is reloaded or restarted.&quot;&lt;/span&gt;;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Copy across the contents of &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; from the old environment to the new (e.g. with rsync).&lt;/p&gt;

&lt;p&gt;Download and run the above script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Make a directory if necessary&lt;/span&gt;
mkdir -p ~/sysadmin/apache
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/sysadmin/apache

&lt;span class=&quot;c&quot;&gt;# Get the script&lt;/span&gt;
curl https://gist.githubusercontent.com/DavidCWebs/509e6e8829e24fb7cfa1e6c82c2b24e2/raw/982693b8de7082acb44082274628de0a63593929/a2enmod-all.sh -o a2enmod-all.sh

&lt;span class=&quot;c&quot;&gt;# Make executable&lt;/span&gt;
sudo chmod +x a2enmod-all.sh

&lt;span class=&quot;c&quot;&gt;# Run script&lt;/span&gt;
sudo ./a2enmod-all.sh&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Move across &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; from the old environment to the new.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;a2ensite&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;a2dissite&lt;/code&gt; &lt;a href=&quot;https://manpages.debian.org/jessie/apache2/a2ensite.8.en.html&quot;&gt;Man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 22 Jun 2017 16:44:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/06/enable-all-apache-config-files/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/06/enable-all-apache-config-files/</guid>
      </item>
      
    
      
      <item>
        <title>Vue Components</title>
        <description>&lt;h1 id=&quot;vue-components&quot;&gt;Vue Components&lt;/h1&gt;
&lt;p&gt;Vue provides a way for you to abstract elements into re-usable pieces (or in other words, components!).&lt;/p&gt;

&lt;p&gt;Vue components are custom elements that have behaviour attached to them by the Vue compiler. For example, you might define an &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;article&amp;gt;&lt;/code&gt; component that encapsulates all the code relating to display of content associated with an article.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I’m new to Vue so please treat this content with suspicion! If you have any Vue tips, or if you’d like to point out where I’m going wrong, please leave a comment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Data can be passed into components by means of &lt;a href=&quot;https://vuejs.org/v2/guide/components.html#Props&quot;&gt;props&lt;/a&gt; and &lt;a href=&quot;https://vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots&quot;&gt;slots&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vue provides several methods for registering and using components. In general, global components are registered by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;Vue.component(id, definition)&lt;/code&gt;, where:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;id&lt;/code&gt; is a string that will be set to the component name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;definition&lt;/code&gt; is a function or an options object (that might define markup, props etc)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;registering-a-component-basic-method&quot;&gt;Registering a Component: Basic Method&lt;/h2&gt;
&lt;p&gt;Register an “news-article” component - defines a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;news-article&amp;gt;&amp;lt;/news-article&amp;gt;&lt;/code&gt; that can be used within HTML:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Register component before instantiating the Vue instance&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Reference the template inline&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'news-article'&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;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;article&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;an&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Article&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/h2&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// New Vue root instance&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#app'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this example, the HTML for the template is passed to the constructor inline. For a project of any size, this is likely to be too messy.&lt;/p&gt;

&lt;p&gt;Another option is to define the HTML for the template as a script tag of type “text/x-template” (which will be ignored by browsers):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/x-template&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;news-article-template&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;an&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Article&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/h2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'news-article'&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;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#news-article-template&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The constructor now references the id of the “text/template” template.&lt;/p&gt;

&lt;p&gt;Note that the order in which you define the template is important. &lt;strong&gt;You must define the &lt;code class=&quot;highlighter-rouge&quot;&gt;text/x-template&lt;/code&gt; tag before you reference it in the &lt;code class=&quot;highlighter-rouge&quot;&gt;Vue.component&lt;/code&gt; constructor.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;registering-a-component-within-a-javascript-file&quot;&gt;Registering a Component: Within a JavaScript File&lt;/h2&gt;
&lt;p&gt;The example below registers a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;custom-note&amp;gt;&amp;lt;/custom-note&amp;gt;&lt;/code&gt; component and defines a prop (&lt;code class=&quot;highlighter-rouge&quot;&gt;title&lt;/code&gt;) that can be passed in to the component. It also sets up validation on the prop - which returns a helpful error if the script runs in development mode.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'custom-note'&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;na&quot;&gt;props&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;na&quot;&gt;title&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;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&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;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;card&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h2&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/h2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/slot&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#root'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A simpler way to define the prop:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'custom-note'&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;na&quot;&gt;props&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;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;card&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h2&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/h2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/slot&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 01 Jun 2017 09:01:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/06/vue-components/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/06/vue-components/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel 5.4 and MariaDB Errors</title>
        <description>&lt;p&gt;When running migrations on Laravel 5.4 and MariaDB you may encounter this error:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))&lt;/p&gt;

  &lt;p&gt;[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;Amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;AppServiceProvider&lt;/code&gt; - which you’ll find here: &lt;code class=&quot;highlighter-rouge&quot;&gt;app/Providers/AppServiceProvider.php&lt;/code&gt;. Use &lt;code class=&quot;highlighter-rouge&quot;&gt;Illuminate\Support\Facades\Schema&lt;/code&gt; to set a default string length which can be used in migrations. The ameded class might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App\Providers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Support\Facades\Schema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Support\ServiceProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AppServiceProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ServiceProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Bootstrap any application services.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;boot&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;nx&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;defaultStringLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;191&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;sd&quot;&gt;/**
     * Register any application services.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;register&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;c1&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;migrate-the-database&quot;&gt;Migrate the Database&lt;/h2&gt;
&lt;p&gt;You may end up with a part-migration error, whereby tables have been created during a broken migration, but the &lt;code class=&quot;highlighter-rouge&quot;&gt;migrations&lt;/code&gt; table is missing. Here’s an example showing the database after receiving the above-quoted error:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Welcome to the MariaDB monitor.  Commands end with ; or &lt;span class=&quot;se&quot;&gt;\g&lt;/span&gt;.
Your MariaDB connection id is 82
Server version: 10.1.23-MariaDB-1~xenial mariadb.org binary distribution

Copyright &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type &lt;span class=&quot;s1&quot;&gt;'help;'&lt;/span&gt; or &lt;span class=&quot;s1&quot;&gt;'\h'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;help. Type &lt;span class=&quot;s1&quot;&gt;'\c'&lt;/span&gt; to clear the current input statement.

MariaDB &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;my_db_dev]&amp;gt; show tables;
+---------------------+
| Tables_in_my_db_dev |
+---------------------+
| migrations          |
| users               |
+---------------------+

2 rows &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.00 sec&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With the database in this state, you won’t be able to &lt;a href=&quot;https://laravel.com/docs/5.4/migrations#rolling-back-migrations&quot;&gt;roll back migrations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To fix, delete the tables manually at the MariaDB prompt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open the MariaDB command line focused on your database:&lt;/span&gt;
mysql -u root -p my_db_dev

&lt;span class=&quot;c&quot;&gt;# Show tables to determine what tables you need to drop:&lt;/span&gt;
SHOW TABLES;

&lt;span class=&quot;c&quot;&gt;# Drop tables:&lt;/span&gt;
DROP TABLE users, migrations;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After manually amending the database, close the MariaDB CLI by typing &lt;code class=&quot;highlighter-rouge&quot;&gt;\q&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point you should be able to run the migration successfully:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sun, 28 May 2017 19:59:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/laravel-5-4-and-mariadb-errors/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/laravel-5-4-and-mariadb-errors/</guid>
      </item>
      
    
      
      <item>
        <title>Nano Highlighting in Config Files</title>
        <description>&lt;p&gt;It’s handy to have syntax highlighting in config files (like &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt; and Apache virtual host configs).&lt;/p&gt;

&lt;p&gt;Nano includes syntax definitions from config files saved in the format &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/nano/*.nanorc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To add syntax highlighting for config files, add the following to &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/nano/conf.nanorc&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;syntax &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\c&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;onf$&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;conf&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bash_profile&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bash_history&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;c$&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|/|)control$&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(repo|conf|config|cfg|cnf|rc|lst|list|defs|ini|desktop|mime|types|preset|cache|seat|service|htaccess)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(^|/)(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\w&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*crontab|mirrorlist|group|hosts|passwd|rpc|netconfig|shadow|fstab|inittab|inputrc|protocols|sudoers)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;conf.d/|.config/)&quot;&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# default text&lt;/span&gt;
color white &lt;span class=&quot;s2&quot;&gt;&quot;^.*$&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# special values&lt;/span&gt;
icolor brightblue &lt;span class=&quot;s2&quot;&gt;&quot;(^|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|=)(default|true|false|on|off|yes|no)(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# keys&lt;/span&gt;
icolor cyan &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*(set&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+)?[A-Z0-9_&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\/\.\%\@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+-]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*([:]|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# commands&lt;/span&gt;
color blue &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*set&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;lt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# punctuation&lt;/span&gt;
color blue &lt;span class=&quot;s2&quot;&gt;&quot;[.]&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# numbers&lt;/span&gt;
color red &lt;span class=&quot;s2&quot;&gt;&quot;(^|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|[[/:|&amp;lt;&amp;gt;(){}=,]|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)[-+]?[0-9](&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;?[0-9])*%?(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# keys&lt;/span&gt;
icolor cyan &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;if )?([A-Z0-9_&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\/\.\%\@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+-]|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)+=&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# punctuation&lt;/span&gt;
color blue &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt;
color brightwhite &lt;span class=&quot;s2&quot;&gt;&quot;(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|[()&amp;lt;&amp;gt;[{},;:=])&quot;&lt;/span&gt;
color brightwhite &lt;span class=&quot;s2&quot;&gt;&quot;(^|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*-(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# section headings&lt;/span&gt;
icolor brightyellow &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;([A-Z0-9_&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-]|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*$&quot;&lt;/span&gt;
color brightcyan &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*((Sub)?Section&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*(=|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)|End(Sub)?Section&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
color brightcyan &lt;span class=&quot;s2&quot;&gt;&quot;^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(end)?if(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# URLs&lt;/span&gt;
icolor green &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(([A-Z]+://|www[.])[A-Z0-9/:#?&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.\-&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;]+)(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; )&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# XML-like tags&lt;/span&gt;
icolor brightcyan &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;/?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\w&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+((&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\w&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*=)?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*(&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;^&lt;span class=&quot;s2&quot;&gt;&quot;]*&quot;&lt;/span&gt;|&lt;span class=&quot;s1&quot;&gt;'[^'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'|!?[A-Z0-9_:/]))*(\s*/)?&amp;gt;&quot;

color green &quot;\&amp;lt;(break|case|continue|do|done|elif|else|esac|exit|fi|for|function|if|in|read|return|select|shift|then|time|until|while)\&amp;gt;&quot;
color green &quot;\&amp;lt;(declare|eval|exec|export|let|local)\&amp;gt;&quot;
color green &quot;[{}():;|`$&amp;lt;&amp;gt;!=&amp;amp;\\]&quot; &quot;(\]|\[)&quot;
color green &quot;-[Ldefgruwx]\&amp;gt;&quot;
color green &quot;-(eq|ne|gt|lt|ge|le|s|n|z)\&amp;gt;&quot;
color brightblue &quot;\&amp;lt;(awk|cat|cd|ch(grp|mod|own)|cp|echo|env|grep|install|ln|make|mkdir|mv|popd|printf|pushd|rm|rmdir|sed|set|tar|touch|umask|unset)\&amp;gt;&quot;

# Basic variable names (no braces).
color brightred &quot;\$[-0-9@*#?$!]&quot; &quot;\$[[:alpha:]_][[:alnum:]_]*&quot;
# More complicated variable names; handles braces and replacements and arrays.
color brightred &quot;\$\{[#!]?([-@*#?$!]|[0-9]+|[[:alpha:]_][[:alnum:]_]*)(\[([[:space:]]*[[:alnum:]_]+[[:space:]]*|@)\])?(([#%/]|:?[-=?+])[^}]*\}|\[|\})&quot;

# Comments.
color brightblack &quot;(^|[[:space:]])#.*$&quot;

# Strings.
color brightyellow &quot;&quot;(\\.|[^&quot;])*&quot;&quot; &quot;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;.|[^&lt;span class=&quot;s1&quot;&gt;'])*'&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;

# Trailing whitespace.
color ,green &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt;:space:]]+&lt;span class=&quot;s2&quot;&gt;$&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 23 May 2017 09:18:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/nano-highlighting-in-config-files/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/nano-highlighting-in-config-files/</guid>
      </item>
      
    
      
      <item>
        <title>Apache Server Security on Ubuntu 16.04 Xenial</title>
        <description>&lt;p&gt;This article lists some sensible configuration defaults for Apache 2.4 on a Ubuntu 16.04 server. It explains how to apply these globally at the server level.&lt;/p&gt;

&lt;p&gt;Objectives:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Prevent the Apache server signature that is printed as part of a web request - this is not needed and gives would-be hackers info about your server&lt;/li&gt;
  &lt;li&gt;Prevent direct access to certain files (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;.git&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;.json&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;.sql&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Prevent directory browsing - don’t allow random strangers to sniff out your directory structure&lt;/li&gt;
  &lt;li&gt;Disallow Apache overrides at the directory level (e.g. disallow config &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that if you disallow &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files you’ll probably need to include suitable rewrite rules in each site’s Apache virtual host configuration. This is not only slightly more secure, it should be faster.&lt;/p&gt;

&lt;h2 id=&quot;global-apache-config&quot;&gt;Global Apache Config&lt;/h2&gt;
&lt;p&gt;Open the Apache config file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/conf-enabled/security.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make the following changes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;#...&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ServerTokens&lt;/span&gt; Prod

&lt;span class=&quot;c&quot;&gt;#...&lt;/span&gt;
Set ServerSignature Off

&lt;span class=&quot;c&quot;&gt;#...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Add the following block:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Prevent access to any .git directory&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;DirectoryMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;/\.git&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;DirectoryMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Protect a specified range of files from direct access&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;^(wp-config\.php|php\.ini|php5\.ini|install\.php|php\.info|readme\.md|README\.md|readme\.html|bb-config\.php|\.htaccess|\.htpasswd|readme\.txt|timthumb\.php|error_log|error\.log|PHP_errors\.log|\.svn)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Prevent access to JSON config files&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;\.(json)$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Prevent access to sql dumps: these should NOT be in your document root, but just in case...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;\.(sql)$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Prevent xmlrpc attacks - if you're not using xmlrpc, block this file to avoid hack attempts&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;^(xmlrpc\.php)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;prevent-embedding-and-sniffing&quot;&gt;Prevent Embedding and Sniffing&lt;/h2&gt;
&lt;p&gt;Set headers for all files served:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;NOSNIFF&lt;/code&gt; header prevents IE mime-sniffing files&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SAMEORIGIN&lt;/code&gt; header prevents embedding of content in different site&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; this modification will cause Apache to fail unless the &lt;code class=&quot;highlighter-rouge&quot;&gt;headers&lt;/code&gt; module is enabled:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod headers
&lt;span class=&quot;c&quot;&gt;# ...and restart Apache&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add the following to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/conf-enabled/security.conf&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Setting this header will prevent MSIE from interpreting files as something&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# else than declared by the content type in the HTTP headers.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Requires mod_headers to be enabled.&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Header&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;set&lt;/span&gt; X-Content-Type-Options: NOSNIFF

&lt;span class=&quot;c&quot;&gt;# Setting this header will prevent other sites from embedding pages from this&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# site as frames. This defends against clickjacking attacks.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Requires mod_headers to be enabled.&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Header&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;set&lt;/span&gt; X-Frame-Options: SAMEORIGIN&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;prevent-directory-browsing&quot;&gt;Prevent Directory Browsing&lt;/h2&gt;
&lt;p&gt;Open the relevant config file for editing:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Consider making a backup of the original first:&lt;/span&gt;
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.bak

&lt;span class=&quot;c&quot;&gt;# Open the file for editing:&lt;/span&gt;
sudo nano /etc/apache2/apache2.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Remove/Comment out:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Indexes&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;FollowSymLinks&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all granted
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add this block:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Disable directory browsing&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Indexes
        &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;FollowSymLinks&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all granted
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo /etc/init.d/apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Your Apache server should now be a bit more secure. The configuration settings have been applied globally - rather than in numerous &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files at the directory level.&lt;/p&gt;
</description>
        <pubDate>Mon, 22 May 2017 08:47:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/apache-server-security/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/apache-server-security/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Database Management</title>
        <description>&lt;p&gt;This article focuses on Laravel 5.4 development in a Ubuntu 16.04 desktop environment. It is assumed that a suitable database has already been created.&lt;/p&gt;

&lt;h2 id=&quot;create-a-database-table&quot;&gt;Create a Database Table&lt;/h2&gt;
&lt;p&gt;The Laravel way involves creating and running a suitable “migration”. Migrations allow the app to create a new table or modify existing tables. Migrations are very powerful - amongst other things, they enable:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Version control of the database&lt;/li&gt;
  &lt;li&gt;Database modifications to be easily rolled-back&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;create-migration&quot;&gt;Create Migration&lt;/h2&gt;
&lt;p&gt;To create a migration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:migration create_users_table&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This creates a new file in the &lt;code class=&quot;highlighter-rouge&quot;&gt;database/migrations&lt;/code&gt; directory. The filename is based on the option passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan make:migration&lt;/code&gt; and a timestamp - for example: &lt;code class=&quot;highlighter-rouge&quot;&gt;database/migrations/2017_05_29_094813_create_users_table.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the migration is to create a new table, you can specify the table name by passing the &lt;code class=&quot;highlighter-rouge&quot;&gt;create&lt;/code&gt; option to &lt;code class=&quot;highlighter-rouge&quot;&gt;make:migration&lt;/code&gt; command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:migration create_users_table --create&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;users&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will stub out the migration file with the specified table. It’s probably a good idea to name the migration descriptively in the imperative case - for example “create_xx_table” or “adding_excerpt_to_posts_table”.&lt;/p&gt;

&lt;p&gt;The following command sets up a migration that will create a database table called “stages”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:migration create_stages_table --table&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;stages&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once the migration has been created, it needs to be run to actually create the database table:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, the migration class will be in  &lt;code class=&quot;highlighter-rouge&quot;&gt;database/migrations/2017_05_20_112319_create_stages_table.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before running the migration and creating the new table, you’ll probably want to add some columns. You can do this by editing the &lt;code class=&quot;highlighter-rouge&quot;&gt;up()&lt;/code&gt; method on the newly created migration. For example, to add a simple title column:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;up&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;nx&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'stages'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Blueprint&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&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;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;increments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'id'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;timestamps&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; you need to ensure that the additional table methods are added BEFORE the &lt;code class=&quot;highlighter-rouge&quot;&gt;timestamps()&lt;/code&gt; method or they won’t be applied.&lt;/p&gt;

&lt;h2 id=&quot;run-or-rollback-migration&quot;&gt;Run or Rollback Migration&lt;/h2&gt;

&lt;p&gt;To apply the changes to the database, you need to run the migration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To rollback a migration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate:rollback&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See: &lt;a href=&quot;https://laravel.com/docs/5.4/migrations#generating-migrations&quot;&gt;https://laravel.com/docs/5.4/migrations#generating-migrations&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;rollback-problems&quot;&gt;Rollback Problems&lt;/h2&gt;
&lt;p&gt;When attempting a rollback for the first time you may experience this error:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PHP Fatal error:  Uncaught UnexpectedValueException:
The stream or file &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/html/test-laravel/storage/logs/laravel.log&quot;&lt;/span&gt;
could not be opened: failed to open stream:
Permission denied &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /var/www/html/test-laravel/vendor
/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This occurs because you’re running the rollback command as your current user. The &lt;code class=&quot;highlighter-rouge&quot;&gt;storage&lt;/code&gt; directory will be owned by the server user (www-data in the case of Ubuntu), and will probably belong to your main user’s group (depending upon how you assigned permissions when you first installed the app).&lt;/p&gt;

&lt;p&gt;The fix is simple - &lt;code class=&quot;highlighter-rouge&quot;&gt;chmod&lt;/code&gt; the log file to give your user write permissions. The file will probably have &lt;code class=&quot;highlighter-rouge&quot;&gt;-rw--r--r--&lt;/code&gt; permissions, so change these to 664:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chmod 664 /var/www/html/test-laravel/storage/logs/laravel.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;seeding-a-table&quot;&gt;Seeding a Table&lt;/h2&gt;
&lt;p&gt;Laravel 5.4 ships with the &lt;code class=&quot;highlighter-rouge&quot;&gt;Faker&lt;/code&gt; Factory class included, which can be used to “seed” the database.&lt;/p&gt;

&lt;p&gt;Create a seeder stub for the ‘stages’ table:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:seeder StagesTableSeeder&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This stubs out a &lt;code class=&quot;highlighter-rouge&quot;&gt;StagesTableSeeder&lt;/code&gt; class in &lt;code class=&quot;highlighter-rouge&quot;&gt;database/seeds/StagesTableSeeder.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example Seeder:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Database\Seeder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UsersTableSeeder&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Seeder&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Run the database seeds.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&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;nx&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;App\User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;defining-model-factories&quot;&gt;Defining Model Factories&lt;/h2&gt;
&lt;p&gt;The method above uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;factory()&lt;/code&gt; helper function. This references a Model Factory that you can create in &lt;code class=&quot;highlighter-rouge&quot;&gt;database/factories&lt;/code&gt;. You could add all factory logic in &lt;code class=&quot;highlighter-rouge&quot;&gt;database/factories/ModelFactory.php&lt;/code&gt; - but it’s easier to keep code organised if you duplicate this file and add factory logic for your models within appropriately named files. For example, &lt;code class=&quot;highlighter-rouge&quot;&gt;database/factories/PostFactory.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
|--------------------------------------------------------------------------
| Model Factory for Posts
|--------------------------------------------------------------------------
|
| Adds a random user_id to the dummy posts.
|
*/&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;/** @var \Illuminate\Database\Eloquent\Factory $factory */&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;App\Post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Faker\Generator&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&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;nv&quot;&gt;$userID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App\User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inRandomOrder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'body'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'excerpt'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'user_id'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$userID&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;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can call the new seeder from the &lt;code class=&quot;highlighter-rouge&quot;&gt;run()&lt;/code&gt; method in &lt;code class=&quot;highlighter-rouge&quot;&gt;seeds/DatabaseSeeder.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Database\Seeder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DatabaseSeeder&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Seeder&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Run the database seeds.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&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;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UsersTableSeeder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PostsTableSeeder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This helps to keep seeder classes nice and neat.&lt;/p&gt;

&lt;p&gt;Run the seeders:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan db:seed&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Rollback all database migrations and re-seed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate:refresh --seed&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sat, 20 May 2017 16:28:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/laravel-database-management/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/laravel-database-management/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Reserved Terms and Post Requests</title>
        <description>&lt;p&gt;When submitting a form to a WordPress site, there are a number of reserved keywords that should not be used as name attributes - including “name”, “author” and “type”. Using such keywords may result in odd errors - either unexplained 404 errors or the template reverting to the &lt;code class=&quot;highlighter-rouge&quot;&gt;index.php&lt;/code&gt; template.&lt;/p&gt;

&lt;p&gt;The latter error looks particularly odd, because the permalink is unchanged. Debugging &lt;code class=&quot;highlighter-rouge&quot;&gt;$_POST&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;$_REQUEST&lt;/code&gt; names in this context is not simple.&lt;/p&gt;

&lt;p&gt;Most recently, when refactoring a project I managed to completely break form submission. The natural assumption is that there is a problem with your code. Eight hours of git resets and diffs later, I realized that I had set a form field with the name attribute “name” - coincidence can be a bitch.&lt;/p&gt;

&lt;p&gt;Since I’ve cumulatively wasted a couple of days of my life on this issue, I’m documenting it here to prevent future nervous meltdowns.&lt;/p&gt;

&lt;h2 id=&quot;prefix-all-form-names&quot;&gt;Prefix all Form Names&lt;/h2&gt;
&lt;p&gt;A good general rule for WordPress forms is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PREFIX FORM NAMES&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;reserved-keywords&quot;&gt;Reserved Keywords&lt;/h2&gt;
&lt;p&gt;I can personally attest that you need to avoid the string “name” as a name attribute (use “my_prefix_name” instead). The rest of the list is taken from the &lt;a href=&quot;https://codex.wordpress.org/Reserved_Terms&quot;&gt;WordPress Codex&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;attachment&lt;/li&gt;
  &lt;li&gt;attachment_id&lt;/li&gt;
  &lt;li&gt;author&lt;/li&gt;
  &lt;li&gt;author_name&lt;/li&gt;
  &lt;li&gt;calendar&lt;/li&gt;
  &lt;li&gt;cat&lt;/li&gt;
  &lt;li&gt;category&lt;/li&gt;
  &lt;li&gt;category__and&lt;/li&gt;
  &lt;li&gt;category__in&lt;/li&gt;
  &lt;li&gt;category__not_in&lt;/li&gt;
  &lt;li&gt;category_name&lt;/li&gt;
  &lt;li&gt;comments_per_page&lt;/li&gt;
  &lt;li&gt;comments_popup&lt;/li&gt;
  &lt;li&gt;custom&lt;/li&gt;
  &lt;li&gt;customize_messenger_channel&lt;/li&gt;
  &lt;li&gt;customized&lt;/li&gt;
  &lt;li&gt;cpage&lt;/li&gt;
  &lt;li&gt;day&lt;/li&gt;
  &lt;li&gt;debug&lt;/li&gt;
  &lt;li&gt;embed&lt;/li&gt;
  &lt;li&gt;error&lt;/li&gt;
  &lt;li&gt;exact&lt;/li&gt;
  &lt;li&gt;feed&lt;/li&gt;
  &lt;li&gt;hour&lt;/li&gt;
  &lt;li&gt;link_category&lt;/li&gt;
  &lt;li&gt;m&lt;/li&gt;
  &lt;li&gt;minute&lt;/li&gt;
  &lt;li&gt;monthnum&lt;/li&gt;
  &lt;li&gt;more&lt;/li&gt;
  &lt;li&gt;name&lt;/li&gt;
  &lt;li&gt;nav_menu&lt;/li&gt;
  &lt;li&gt;nonce&lt;/li&gt;
  &lt;li&gt;nopaging&lt;/li&gt;
  &lt;li&gt;offset&lt;/li&gt;
  &lt;li&gt;order&lt;/li&gt;
  &lt;li&gt;orderby&lt;/li&gt;
  &lt;li&gt;p&lt;/li&gt;
  &lt;li&gt;page&lt;/li&gt;
  &lt;li&gt;page_id&lt;/li&gt;
  &lt;li&gt;paged&lt;/li&gt;
  &lt;li&gt;pagename&lt;/li&gt;
  &lt;li&gt;pb&lt;/li&gt;
  &lt;li&gt;perm&lt;/li&gt;
  &lt;li&gt;post&lt;/li&gt;
  &lt;li&gt;post__in&lt;/li&gt;
  &lt;li&gt;post__not_in&lt;/li&gt;
  &lt;li&gt;post_format&lt;/li&gt;
  &lt;li&gt;post_mime_type&lt;/li&gt;
  &lt;li&gt;post_status&lt;/li&gt;
  &lt;li&gt;post_tag&lt;/li&gt;
  &lt;li&gt;post_type&lt;/li&gt;
  &lt;li&gt;posts&lt;/li&gt;
  &lt;li&gt;posts_per_archive_page&lt;/li&gt;
  &lt;li&gt;posts_per_page&lt;/li&gt;
  &lt;li&gt;preview&lt;/li&gt;
  &lt;li&gt;robots&lt;/li&gt;
  &lt;li&gt;s&lt;/li&gt;
  &lt;li&gt;search&lt;/li&gt;
  &lt;li&gt;second&lt;/li&gt;
  &lt;li&gt;sentence&lt;/li&gt;
  &lt;li&gt;showposts&lt;/li&gt;
  &lt;li&gt;static&lt;/li&gt;
  &lt;li&gt;subpost&lt;/li&gt;
  &lt;li&gt;subpost_id&lt;/li&gt;
  &lt;li&gt;tag&lt;/li&gt;
  &lt;li&gt;tag__and&lt;/li&gt;
  &lt;li&gt;tag__in&lt;/li&gt;
  &lt;li&gt;tag__not_in&lt;/li&gt;
  &lt;li&gt;tag_id&lt;/li&gt;
  &lt;li&gt;tag_slug__and&lt;/li&gt;
  &lt;li&gt;tag_slug__in&lt;/li&gt;
  &lt;li&gt;taxonomy&lt;/li&gt;
  &lt;li&gt;tb&lt;/li&gt;
  &lt;li&gt;term&lt;/li&gt;
  &lt;li&gt;terms&lt;/li&gt;
  &lt;li&gt;theme&lt;/li&gt;
  &lt;li&gt;title&lt;/li&gt;
  &lt;li&gt;type&lt;/li&gt;
  &lt;li&gt;w&lt;/li&gt;
  &lt;li&gt;withcomments&lt;/li&gt;
  &lt;li&gt;withoutcomments&lt;/li&gt;
  &lt;li&gt;year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a more extensive list &lt;a href=&quot;https://wordpress.stackexchange.com/a/77339/67129&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Reserved_Terms&quot;&gt;Codex Article list of reserved terms&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/WordPress_Query_Vars&quot;&gt;WordPress Query variables&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wordpress.stackexchange.com/a/77339/67129&quot;&gt;Stack overflow answer with list of names to avoid&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 17 May 2017 11:21:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/wordpress-reserved-terms-and-post-requests/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/wordpress-reserved-terms-and-post-requests/</guid>
      </item>
      
    
      
      <item>
        <title>Reset Project to the Last Git Commit</title>
        <description>&lt;p&gt;When you’ve made a mess of your code and you need to reset your project to the last git commit.&lt;/p&gt;

&lt;p&gt;Reset changes and remove untracked files from the working tree:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /path/to/project
git reset HEAD --hard
git clean -fd&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-reset&quot;&gt;Git reset&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-clean&quot;&gt;Git clean&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 05 May 2017 13:56:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/05/reset-project-to-the-last-git-commit/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/05/reset-project-to-the-last-git-commit/</guid>
      </item>
      
    
      
      <item>
        <title>Using Bootstrap 4 &amp; Laravel Mix - Autoload Tether</title>
        <description>&lt;p&gt;If you are using Bootstrap 4 with Laravel 5.4, you may encounter a problem related to &lt;a href=&quot;http://tether.io/&quot;&gt;Tether&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bootstrap 4 requires Tether. Running the default &lt;a href=&quot;https://github.com/JeffreyWay/laravel-mix&quot;&gt;Laravel mix&lt;/a&gt; &lt;a href=&quot;https://webpack.js.org/&quot;&gt;webpack&lt;/a&gt; config throws an error because the Tether module is not available as a variable in the Bootstrap module. You might get a Console error like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Uncaught Error: Bootstrap tooltips require Tether (http://tether.io/)
    at app.f3e519c….js:14883
    at app.f3e519c….js:15484
    at Object.&amp;lt;anonymous&amp;gt; (app.f3e519c….js:15669)
    at Object.VERSION (app.f3e519c….js:15671)
    at __webpack_require__ (app.f3e519c….js:20)
    at Object.&amp;lt;anonymous&amp;gt; (app.f3e519c….js:12095)
    at Object.&amp;lt;anonymous&amp;gt; (app.f3e519c….js:12129)
    at __webpack_require__ (app.f3e519c….js:20)
    at Object.&amp;lt;anonymous&amp;gt; (app.f3e519c….js:11192)
    at __webpack_require__ (app.f3e519c….js:20)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Fortunately there’s a pretty easy fix.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;Laravel mix has an &lt;code class=&quot;highlighter-rouge&quot;&gt;autoload()&lt;/code&gt; method that requires modules wherever they are needed.&lt;/p&gt;

&lt;p&gt;To fix the &lt;code class=&quot;highlighter-rouge&quot;&gt;Tether&lt;/code&gt; issue, add this to &lt;code class=&quot;highlighter-rouge&quot;&gt;webpack.mix.js&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;autoload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;tether&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;s1&quot;&gt;'Tether'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'window.Tether'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This requires &lt;code class=&quot;highlighter-rouge&quot;&gt;tether&lt;/code&gt; wherever either the variable &lt;code class=&quot;highlighter-rouge&quot;&gt;Tether&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;window.Tether&lt;/code&gt; is referenced (in this case, by Bootstrap). I think Bootstrap 4 uses the latter.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/JeffreyWay/laravel-mix/blob/master/docs/autoloading.md&quot;&gt;Laravel Mix Autoloading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 30 Apr 2017 18:02:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/04/using-bootstrap-4-laravel-mix-autoload-tether/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/04/using-bootstrap-4-laravel-mix-autoload-tether/</guid>
      </item>
      
    
      
      <item>
        <title>Managing Dependencies in a Laravel Package</title>
        <description>&lt;p&gt;When developing a custom Laravel package, you may need to require a separate package to provide functionality.&lt;/p&gt;

&lt;p&gt;Composer makes it easy to include packages as a dependency. This is a good thing as it makes code more maintainable and means to don’t have to re-invent the wheel.&lt;/p&gt;

&lt;p&gt;You also need to bind the third-party package to the Laravel app - you shouldn’t do this manually, as it would make using your package unecessarily complicated. Fortunately, Laravel makes it easy for you to register packages from within your custom package’s service provider class.&lt;/p&gt;

&lt;h2 id=&quot;use-composer-to-bundle-dependencies&quot;&gt;Use Composer to Bundle Dependencies&lt;/h2&gt;

&lt;p&gt;In this example, we’ll add the “illuminate/support” and “laravelcollective/html” packages. In your custom package &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;illuminate/support&quot;&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;s2&quot;&gt;&quot;5.4.*&quot;&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;nt&quot;&gt;&quot;laravelcollective/html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^5.4.0&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When you run &lt;code class=&quot;highlighter-rouge&quot;&gt;composer update&lt;/code&gt; at the app level, Composer is smart enough to connect the dots and add the required packages to the app &lt;code class=&quot;highlighter-rouge&quot;&gt;vendor&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2 id=&quot;register-services&quot;&gt;Register Services&lt;/h2&gt;

&lt;p&gt;Within the &lt;code class=&quot;highlighter-rouge&quot;&gt;boot()&lt;/code&gt; method of the custom packages service provider, you can register (bind) the “laravelcollective/html” service provider. You can also load up an alias for the package:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Carawebs\Blog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Foundation\AliasLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Illuminate\Support\ServiceProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Collective\Html\HtmlServiceProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;/**
 * Bind to the Laravel service container.
 * This class should be included in the Laravel app's
 * `config/app.php` 'providers' array.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlogProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ServiceProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
    * Bootstrap the application services.
    *
    * @return void
    */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;boot&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;c1&quot;&gt;// Register the HtmlServiceProvider class - like you'd generally do in the
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// `config/app.php` 'providers' array.
&lt;/span&gt;        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HtmlServiceProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$loader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AliasLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$loader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Form'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\Collective\Html\FormFacade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Unrelated
&lt;/span&gt;        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadRoutesFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__DIR__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/routes.php'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadMigrationsFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__DIR__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/migrations'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadViewsFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__DIR__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/views'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'blog'&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You could simplify the alias loading by passing in an array of alias =&amp;gt; classname values to the &lt;code class=&quot;highlighter-rouge&quot;&gt;getInstance()&lt;/code&gt; method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ...
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AliasLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Form'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'\Collective\Html\FormFacade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This method acceps an array and merges this with the registered aliases.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;See &lt;code class=&quot;highlighter-rouge&quot;&gt;$this-&amp;gt;app-&amp;gt;register()&lt;/code&gt; method &lt;a href=&quot;https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/Application.php#L554&quot;&gt;on GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;See &lt;code class=&quot;highlighter-rouge&quot;&gt;AliasLoader::alias()&lt;/code&gt; method &lt;a href=&quot;https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/AliasLoader.php#L140&quot;&gt;on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 26 Mar 2017 15:22:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2017/03/managing-dependencies-in-a-laravel-package/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/managing-dependencies-in-a-laravel-package/</guid>
      </item>
      
    
      
      <item>
        <title>Manage WordPress Plugins Using Composer</title>
        <description>&lt;p&gt;This article shows how to use Composer to manage project plugin dependencies.&lt;/p&gt;

&lt;p&gt;The example given is for a &lt;a href=&quot;https://roots.io/bedrock/&quot;&gt;Bedrock&lt;/a&gt; project. Bedrock is an improved WordPress project structure from the &lt;a href=&quot;https://roots.io/&quot;&gt;Roots&lt;/a&gt; team that manages dependencies with &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;manage-plugins-from-the-wordpress-plugin-directory&quot;&gt;Manage Plugins from The WordPress Plugin Directory&lt;/h2&gt;
&lt;p&gt;You can easily access any plugin that’s held in the &lt;a href=&quot;https://wordpress.org/plugins/&quot;&gt;WordPress Plugin Directory&lt;/a&gt; by means of the &lt;a href=&quot;https://wpackagist.org/&quot;&gt;WordPress Packagist&lt;/a&gt; Composer repository.&lt;/p&gt;

&lt;p&gt;WordPress Packagist mirrors the WordPress plugin and theme directories. If you add the wpackagist repository to Composer’s “repositories”, you can then require the ACF free version.&lt;/p&gt;

&lt;p&gt;In Bedrock’s &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; add the wp-packagist repo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;repositories&quot;&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;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;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;composer&quot;&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;nt&quot;&gt;&quot;url&quot;&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;s2&quot;&gt;&quot;https://wpackagist.org&quot;&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;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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then in the same file, require the plugin:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;php&quot;&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;s2&quot;&gt;&quot;&amp;gt;=5.6&quot;&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;nt&quot;&gt;&quot;composer/installers&quot;&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;s2&quot;&gt;&quot;~1.0.12&quot;&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;nt&quot;&gt;&quot;vlucas/phpdotenv&quot;&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;s2&quot;&gt;&quot;^2.0.1&quot;&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;nt&quot;&gt;&quot;johnpbloch/wordpress&quot;&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;s2&quot;&gt;&quot;4.7.2&quot;&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;nt&quot;&gt;&quot;oscarotero/env&quot;&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;s2&quot;&gt;&quot;^1.0&quot;&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;nt&quot;&gt;&quot;roots/wp-password-bcrypt&quot;&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;s2&quot;&gt;&quot;1.0.0&quot;&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;nt&quot;&gt;&quot;roots/soil&quot;&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;s2&quot;&gt;&quot;3.7.1&quot;&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;nt&quot;&gt;&quot;wpackagist-plugin/advanced-custom-fields&quot;&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;s2&quot;&gt;&quot;4.1.*&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;composer update&lt;/code&gt; and it should fetch the plugin.&lt;/p&gt;

&lt;h2 id=&quot;custom-plugins-not-in-the-wordpress-directory&quot;&gt;Custom Plugins: Not in the WordPress Directory&lt;/h2&gt;
&lt;p&gt;We use a lot of custom plugins - the easiest way to manage these is to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Push your code to a public VCS (e.g. git) repo (GitHub, BitBucket)&lt;/li&gt;
  &lt;li&gt;Set them up as a Composer package on &lt;a href=&quot;https://packagist.org/&quot;&gt;Packagist&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;In the plugin’s &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;, make sure you set &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;type&quot;: &quot;wordpress-plugin&quot;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Require the plugin in the project &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s an example from a Bedrock project &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; - this requires the &lt;code class=&quot;highlighter-rouge&quot;&gt;carawebs/wp-custom-content&lt;/code&gt; Composer package (which is a WordPress plugin that sets up custom post types from a config array):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;php&quot;&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;s2&quot;&gt;&quot;&amp;gt;=5.6&quot;&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;nt&quot;&gt;&quot;composer/installers&quot;&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;s2&quot;&gt;&quot;~1.0.12&quot;&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;nt&quot;&gt;&quot;vlucas/phpdotenv&quot;&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;s2&quot;&gt;&quot;^2.0.1&quot;&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;nt&quot;&gt;&quot;johnpbloch/wordpress&quot;&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;s2&quot;&gt;&quot;4.7.3&quot;&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;nt&quot;&gt;&quot;oscarotero/env&quot;&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;s2&quot;&gt;&quot;^1.0&quot;&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;nt&quot;&gt;&quot;roots/wp-password-bcrypt&quot;&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;s2&quot;&gt;&quot;1.0.0&quot;&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;nt&quot;&gt;&quot;carawebs/wp-custom-content&quot;&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;s2&quot;&gt;&quot;dev-master&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;composer update&lt;/code&gt; then instructs Composer to download the plugin to the appropriate directory - in the case of Bedrock, &lt;code class=&quot;highlighter-rouge&quot;&gt;/web/app/plugins&lt;/code&gt;. You can also take advantage of Composer autoloading - in the plugin &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; set the appropriate directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;autoload&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;psr-4&quot;&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;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;Carawebs\\CustomContent\\&quot;&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;s2&quot;&gt;&quot;src&quot;&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;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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assuming that you’re using Composer autoloading, you’ll now be able to access your plugin’s namespaced classes using the namespace you’ve defined (in the example above, &lt;code class=&quot;highlighter-rouge&quot;&gt;Carawebs\CustomContent\ClassName&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;access-specific-commits&quot;&gt;Access Specific Commits&lt;/h2&gt;
&lt;p&gt;You can request a specific tagged commit - so in the example above, you could create a git tag 1.0.0 and specifically require this in the project &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;carawebs/wp-custom-content&quot;&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;s2&quot;&gt;&quot;1.0.0&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can also access branches - using the branch name as a suffix on ‘dev-‘ like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;carawebs/wp-custom-content&quot;&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;s2&quot;&gt;&quot;dev-experimental-branch&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This can be useful if you want to build functionality as a pure Composer library rather than a plugin - you can keep this code in a ‘library’ branch on your git repo. This might be useful if you needed to include your functionality in another plugin.&lt;/p&gt;
</description>
        <pubDate>Fri, 24 Mar 2017 11:06:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/manage-wordpress-plugins-using-composer/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/manage-wordpress-plugins-using-composer/</guid>
      </item>
      
    
      
      <item>
        <title>Filtering the WordPress Menu</title>
        <description>&lt;p&gt;You can filter both the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag and the contained anchor tag in a WordPress menu using the ‘nav_menu_css_class’ and ‘nav_menu_link_attributes’ filters.&lt;/p&gt;

&lt;p&gt;The ‘nav_menu_link_attributes’ and ‘nav_menu_css_class’ filters are not well documented - but very useful nonetheless. You can see the filters in &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-includes/class-walker-nav-menu.php&lt;/code&gt; on line 136 and 179.&lt;/p&gt;

&lt;p&gt;This example shows how to add the required classes for a Bootstrap 4 menu markup - in which the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;li&amp;gt;&lt;/code&gt; requires the class &lt;code class=&quot;highlighter-rouge&quot;&gt;nav-item&lt;/code&gt; and the anchor tag requires the class &lt;code class=&quot;highlighter-rouge&quot;&gt;nav-link&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;add_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nav_menu_css_class'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$classes&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;nv&quot;&gt;$classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nav-item'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$classes&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;mi&quot;&gt;10&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;nx&quot;&gt;add_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nav_menu_link_attributes'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$atts&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;nv&quot;&gt;$atts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'class'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;nav-link&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$atts&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;mi&quot;&gt;100&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Fri, 24 Mar 2017 10:15:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/filtering-the-wordpress-menu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/filtering-the-wordpress-menu/</guid>
      </item>
      
    
      
      <item>
        <title>Initial Workflow for Composer Package Development</title>
        <description>&lt;p&gt;During the initial stages of developing a &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; package, you probably don’t want to go to the trouble of setting up an empty &lt;a href=&quot;https://packagist.org/&quot;&gt;Packagist&lt;/a&gt; package. You probably also shouldn’t be developing in the vendor directory.&lt;/p&gt;

&lt;p&gt;I haven’t done much research on the best workflow for this solution - but the method described in this article, which utilises a Composer path repository - seems to work pretty well. I heard Taylor Otwell (creator of Laravel) talk at &lt;a href=&quot;https://laracon.net/&quot;&gt;Laracon Online&lt;/a&gt; last week and he uses this approach.&lt;/p&gt;

&lt;h2 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;/h2&gt;
&lt;p&gt;In your project root directory, create a ‘packages’ directory. This in turn should contain a ‘vendor-name’ directory which shouild contain a ‘package-name’ directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /path/to/project/root
mkdir -p packages/vendor-name/project-name&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I think it’s best to name directories according to &lt;a href=&quot;https://packagist.org/about#naming-your-package&quot;&gt;Packagist naming conventions&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;composer-init-in-the-new-project&quot;&gt;Composer Init in the New Project&lt;/h2&gt;
&lt;p&gt;Move into your project and run &lt;code class=&quot;highlighter-rouge&quot;&gt;composer init&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;packages/vendor-name/project-name
composer init&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Composer will prompt you to set important metadata like the package name. This will be needed later when Composer (at the parent project level) attempts to auto-load your new project files.&lt;/p&gt;

&lt;h2 id=&quot;set-up-path-repository&quot;&gt;Set Up Path Repository&lt;/h2&gt;
&lt;p&gt;In the &lt;strong&gt;main project&lt;/strong&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;, you need to create a path reference for your package within the “repositories” section. The following fragment from the parent project &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; defines two Composer path repositories, &lt;code class=&quot;highlighter-rouge&quot;&gt;sage-blade-data&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-metadata-accessor&lt;/code&gt;. In this particular case, the parent project is cloned from the &lt;a href=&quot;https://roots.io/sage/&quot;&gt;Sage WordPress starter theme&lt;/a&gt; - which comes already set-up for Composer.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;repositories&quot;&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;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;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;path&quot;&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;nt&quot;&gt;&quot;url&quot;&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;s2&quot;&gt;&quot;./packages/carawebs/sage-blade-data&quot;&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;path&quot;&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;nt&quot;&gt;&quot;url&quot;&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;s2&quot;&gt;&quot;./packages/carawebs/wp-metadata-accessor&quot;&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;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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;require-local-packages-in-composerjson&quot;&gt;Require Local Packages in composer.json&lt;/h2&gt;
&lt;p&gt;Once the repositories have been set up with the correct path, you can add them to the project dependencies, as shown in this extract:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;php&quot;&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;s2&quot;&gt;&quot;&amp;gt;=5.6.4&quot;&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;nt&quot;&gt;&quot;composer/installers&quot;&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;s2&quot;&gt;&quot;~1.0&quot;&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;nt&quot;&gt;&quot;illuminate/view&quot;&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;s2&quot;&gt;&quot;~5.4.0&quot;&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;nt&quot;&gt;&quot;illuminate/config&quot;&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;s2&quot;&gt;&quot;~5.4.0&quot;&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;nt&quot;&gt;&quot;carawebs/sage-blade-data&quot;&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;s2&quot;&gt;&quot;dev-master&quot;&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;nt&quot;&gt;&quot;carawebs/wp-metadata-accessor&quot;&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;s2&quot;&gt;&quot;dev-master&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: if you have a local repo without releases (maybe you haven’t even run &lt;code class=&quot;highlighter-rouge&quot;&gt;git init&lt;/code&gt; yet), you need to specify &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;dev-master&quot;&lt;/code&gt; for the required local packages. &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;*&quot;&lt;/code&gt; won’t work.&lt;/p&gt;

&lt;h2 id=&quot;autoloading&quot;&gt;Autoloading&lt;/h2&gt;
&lt;p&gt;Within the &lt;strong&gt;new project&lt;/strong&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt;, set up autoloading paths:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;name&quot;&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;s2&quot;&gt;&quot;carawebs/sage-blade-data&quot;&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;nt&quot;&gt;&quot;description&quot;&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;s2&quot;&gt;&quot;Data controllers for Sage 9 WordPress theme - insert data into Blade templates.&quot;&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;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;library&quot;&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;nt&quot;&gt;&quot;license&quot;&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;s2&quot;&gt;&quot;GPL&quot;&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;nt&quot;&gt;&quot;authors&quot;&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;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;nt&quot;&gt;&quot;name&quot;&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;s2&quot;&gt;&quot;David Egan&quot;&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;nt&quot;&gt;&quot;email&quot;&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;s2&quot;&gt;&quot;david@carawebs.com&quot;&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;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;autoload&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;psr-4&quot;&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;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;Carawebs\\SageBladeData\\&quot;&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;s2&quot;&gt;&quot;&quot;&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;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;require&quot;&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;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This sets the new project’s namespace. Once you’ve run &lt;code class=&quot;highlighter-rouge&quot;&gt;composer update&lt;/code&gt;, your project classes will be autoloaded.&lt;/p&gt;

&lt;h2 id=&quot;composer-update-connects-symlinks-things-up&quot;&gt;Composer Update Connects (Symlinks) Things Up&lt;/h2&gt;
&lt;p&gt;Run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;composer update&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the &lt;strong&gt;parent project root directory&lt;/strong&gt;. Composer will then create a new vendor-name directory with the project &lt;code class=&quot;highlighter-rouge&quot;&gt;vendor&lt;/code&gt; directory. The package files will be symlinked here. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /path/parent-project/vendor/carawebs

&lt;span class=&quot;gp&quot;&gt;david@david-desktop:/path/parent-project/vendor/carawebs$ &lt;/span&gt;ls -la
total 8
drwxrwxr-x  2 david david 4096 Mar 16 18:27 .
drwxrwxr-x 11 david david 4096 Mar 16 18:27 ..
lrwxrwxrwx  1 david david   39 Mar 16 15:21 sage-blade-data -&amp;gt; ../../packages/carawebs/sage-blade-data
lrwxrwxrwx  1 david david   44 Mar 16 18:27 wp-metadata-accessor -&amp;gt; ../../packages/carawebs/wp-metadata-accessor&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This allows you to work on your new package from within your &lt;code class=&quot;highlighter-rouge&quot;&gt;packages&lt;/code&gt; directory, but still have your project included within Composer (with dependencies, autoloading, etc).&lt;/p&gt;

&lt;h2 id=&quot;composer-update-problems&quot;&gt;Composer Update Problems&lt;/h2&gt;
&lt;p&gt;I recently hit a snag when setting up a package for development in a Laravel project:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Updating dependencies &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;including require-dev&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Your requirements could not be resolved to an installable &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;of packages.

  Problem 1
    - The requested package carawebs/repositories dev-master exists as carawebs/repositories[dev-repo-pattern] but these are rejected by your constraint.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This happens because if the path-repository project that you’re requiring is not a VCS repository, you need to explicitly define the version in the package &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; file:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the package is a local VCS repository, the version may be inferred by the branch or tag that is currently checked out. Otherwise, the version should be explicitly defined in the package’s composer.json file. If the version cannot be resolved by these means, it is assumed to be dev-master.&lt;/p&gt;

  &lt;p&gt;— &lt;a href=&quot;https://getcomposer.org/doc/05-repositories.md#path&quot;&gt;Composer documentation&lt;/a&gt; on path repositories.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my case, I solved the issue simply by running &lt;code class=&quot;highlighter-rouge&quot;&gt;git init&lt;/code&gt; in the package directory.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://getcomposer.org/doc/05-repositories.md#path&quot;&gt;Composer docs on path repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/36763214&quot;&gt;SO Answer&lt;/a&gt; outlines the “dev-master” issue&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 16 Mar 2017 19:40:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/initial-workflow-for-composer-package-development/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/initial-workflow-for-composer-package-development/</guid>
      </item>
      
    
      
      <item>
        <title>Arrow Functions in ECMAScript 6</title>
        <description>&lt;p&gt;ES6 introduces a new syntax for writing JavaScript functions: arrow functions. Arrow function expressions have more concise syntax than a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function&quot;&gt;function expression&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Arrow functions also allow you to access &lt;code class=&quot;highlighter-rouge&quot;&gt;this&lt;/code&gt; from a surrounding method.&lt;/p&gt;

&lt;p&gt;Arrow functions can have either a “concise body” or a “block body” form:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                  &lt;span class=&quot;c1&quot;&gt;// concise syntax, implied &quot;return&quot;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&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;c1&quot;&gt;// with block body, explicit &quot;return&quot; needed&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;Example from MDN Article on Arrow Functions&lt;/a&gt; by Mozilla Contributors, licensed under &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/2.5/&quot;&gt;CC-BY-SA 2.5&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These are equivalent:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// ES5&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ES5&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;calc2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ES6 Arrow syntax&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arrowCalc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ES6 Short syntax Arrow - note no 'return' keyword, braces&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;shortArrow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;These are also equivalent:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'cat'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'dog'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'elephant'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'crow'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wordsLength1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;word&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wordsLength2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&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;c1&quot;&gt;// If a single parameter is being passed in as an identifier, you can omit parentheses&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// If an expression follows the arrow it will be returned - no return keyword necessary/allowed&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wordsLength3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;Example adapted from MDN Article on Arrow Functions&lt;/a&gt; by Mozilla Contributors, licensed under &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/2.5/&quot;&gt;CC-BY-SA 2.5&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;implicit-return&quot;&gt;Implicit Return&lt;/h2&gt;
&lt;p&gt;Implicit return only happens for single statement arrow functions. If an arrow function is declared with {}, even if it’s a single statement, implicit return does not occur.&lt;/p&gt;

&lt;h2 id=&quot;returning-object-literals&quot;&gt;Returning Object Literals&lt;/h2&gt;
&lt;p&gt;Wrap the object literal in parentheses - code inside &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;&lt;/code&gt; is parsed as a sequence of statements.&lt;/p&gt;

&lt;p&gt;Function that returns an object:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'McLane'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;line-breaks&quot;&gt;Line Breaks&lt;/h2&gt;
&lt;p&gt;Line breaks between parameters and the arrow are not allowed.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions&quot;&gt;MDN Article on Arrow Functions&lt;/a&gt; - good reference article&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://exploringjs.com/es6/ch_arrow-functions.html&quot;&gt;Good description of Arrow Funcions&lt;/a&gt; - outlines lexical variables in arrow functions&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 14 Mar 2017 21:47:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/arrow-functions-in-ecmascript-6/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/arrow-functions-in-ecmascript-6/</guid>
      </item>
      
    
      
      <item>
        <title>Webpack Configuration for JavaScript, CSS and Babel</title>
        <description>&lt;p&gt;Notes on configuring and using Webpack 2.x for JavaScript and CSS. This article includes a description of the use of &lt;a href=&quot;https://babeljs.io/&quot;&gt;Babel&lt;/a&gt;, so that next generation JavaScript can be used whilst maintaining browser compatibility.&lt;/p&gt;

&lt;p&gt;These are personal notes that I’m making these as I learn Webpack. I favour &lt;a href=&quot;https://yarnpkg.com/en/&quot;&gt;Yarn&lt;/a&gt; over NPM, and the notes reflect this. You could always use NPM to manage dependencies.&lt;/p&gt;

&lt;h2 id=&quot;why-webpack&quot;&gt;Why Webpack?&lt;/h2&gt;
&lt;p&gt;Webpack is a tool that bundles modules (files) for your application. It can use &lt;a href=&quot;https://webpack.github.io/docs/loaders.html&quot;&gt;loaders&lt;/a&gt; to transform non JS resources (like CSS) into JavaScript. Webpack has a rich plugin system. Webpack facilitates code-splitting, which aids in project organisation. In short, it is a very versatile build tool for all your front-end assets.&lt;/p&gt;

&lt;p&gt;There are four core concepts that underpin webpack:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Entry: Once an entry point is defined, webpack can work out dependencies and what to bundle.&lt;/li&gt;
  &lt;li&gt;Output: Define the name and location of the bundle to be emitted.&lt;/li&gt;
  &lt;li&gt;Loaders: In webpack, files are treated as modules - but webpack only understands JavaScript. Loaders transform resource files so that webpack can use them.&lt;/li&gt;
  &lt;li&gt;Plugins: Extensible functionality by means of a powerful &amp;amp; customizable plugin system.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;install-webpack-in-project&quot;&gt;Install Webpack in Project&lt;/h2&gt;
&lt;p&gt;This command installs webpack as a project dev dependency.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /path/my-project
&lt;span class=&quot;c&quot;&gt;# If necessary, initialise a package&lt;/span&gt;
yarn init

&lt;span class=&quot;c&quot;&gt;# Install Webpack&lt;/span&gt;
yarn add webpack --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You should now see webpack listed in the &lt;code class=&quot;highlighter-rouge&quot;&gt;devDependencies&lt;/code&gt; section of your &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;run-from-cli&quot;&gt;Run From CLI&lt;/h2&gt;
&lt;p&gt;To see Webpack in basic operation, create a file &lt;code class=&quot;highlighter-rouge&quot;&gt;src/main.js&lt;/code&gt; in your project root. Run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;webpack src/main.js dist/bundle.js&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Webpack will compile &lt;code class=&quot;highlighter-rouge&quot;&gt;src/main.js&lt;/code&gt; down to &lt;code class=&quot;highlighter-rouge&quot;&gt;dist/bundle.js&lt;/code&gt;, which then can be referenced in your HTML.&lt;/p&gt;

&lt;h2 id=&quot;define-script-in-packagejson&quot;&gt;Define Script in package.json&lt;/h2&gt;
&lt;p&gt;For convenience, you could define a webpack command in the &lt;code class=&quot;highlighter-rouge&quot;&gt;scripts&lt;/code&gt; section of &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;scripts&quot;&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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;build&quot;&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;s2&quot;&gt;&quot;webpack src/main.js dist/bundle.js&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;yarn build&lt;/code&gt; will now trigger the webpack task.&lt;/p&gt;

&lt;h2 id=&quot;reference-extra-files&quot;&gt;Reference Extra Files&lt;/h2&gt;
&lt;p&gt;In Node.js, there are two module systems that you can choose to import/export functionality between files:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Import modules using &lt;code class=&quot;highlighter-rouge&quot;&gt;require&lt;/code&gt; and export using &lt;code class=&quot;highlighter-rouge&quot;&gt;module.exports&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Import using ES6 &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt; and export using ES6 &lt;code class=&quot;highlighter-rouge&quot;&gt;export&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you add additional JavaScript files, you can reference them in the entry-point JS file like this (CommonJS):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/main.js&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./additional.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// src/additional.js&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;This is additional.js&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Or like this (ES6):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/main.js&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'./additional.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// src/additional.js&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;This is additional.js&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;loaders&quot;&gt;Loaders&lt;/h2&gt;
&lt;p&gt;To add CSS to the application, webpack needs to load the stylesheet in the entry JavaScript file. Because webpack can only handle JavaScript, a “Loader” is needed to process CSS. In this case, the required loader is &lt;code class=&quot;highlighter-rouge&quot;&gt;css-loader&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To apply the stylesheet, processing the CSS isn’t enough - the resultant style rules need to be injected inline. This is achieved with the &lt;code class=&quot;highlighter-rouge&quot;&gt;style-loader&lt;/code&gt; Loader.&lt;/p&gt;

&lt;p&gt;To install both loaders in the project using Yarn:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yarn add css-loader style-loader --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;using-loaders&quot;&gt;Using Loaders&lt;/h2&gt;
&lt;p&gt;You can call loaders “inline” when requiring modules in the entry point JavaScript file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;!style-loader!css-loader!./main.css&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This shows the syntax for applying loaders within the &lt;code class=&quot;highlighter-rouge&quot;&gt;require&lt;/code&gt; statement. As we’ll see, it’s easier to define loaders in a config file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be careful that you’re not looking at the docs for webpack 1.x: the old syntax does not require the &lt;code class=&quot;highlighter-rouge&quot;&gt;-loader&lt;/code&gt; suffix.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note that the loaders are applied in a right-to-left order - and the order is important. In this case, the processed CSS must be piped to the style loader.&lt;/p&gt;

&lt;p&gt;Apparently you can &lt;a href=&quot;https://webpack.js.org/concepts/loaders/#via-cli&quot;&gt;use loaders through the webpack CLI&lt;/a&gt; - but I wasn’t able to get this working on Ubuntu 16.04.&lt;/p&gt;

&lt;h2 id=&quot;webpack-config&quot;&gt;Webpack Config&lt;/h2&gt;
&lt;p&gt;Webpack configuration can be defined in a configuration file. This drastically simplifies the entry-point JavaScript and makes code more concise and maintainable.&lt;/p&gt;

&lt;p&gt;The webpack config file is a JS file that exports an object. The object is processed by webpack based on the defined properties. The config file is a standard Node.js CommonJS module.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;module.rules&lt;/code&gt;property of &lt;code class=&quot;highlighter-rouge&quot;&gt;webpack.config.js&lt;/code&gt; allows you to specify loaders for particular file types:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// webpack.config.js&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Configure CSS processing &amp;amp; injection&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;webpack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'webpack'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'path'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'./src/main.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;output&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;c1&quot;&gt;// Webpack prefers an absolute path:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;__dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'./dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bundle.js'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;module&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;na&quot;&gt;rules&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;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Uses regex to test for a file type - in this case, ends with `.css`&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;css$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Apply these loaders if test returns true&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;use&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;s1&quot;&gt;'style-loader'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'css-loader'&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;p&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the order in which loaders is applied is important - the right-most loader is applied first.&lt;/p&gt;

&lt;h2 id=&quot;write-es2015es6---for-all-browsers&quot;&gt;Write ES2015/ES6 - For All Browsers&lt;/h2&gt;
&lt;p&gt;Use next gen JavaScript today - using &lt;a href=&quot;http://babeljs.io/&quot;&gt;Babel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, pull in the Babel node module:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yarn add babel-loader babel-core --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You also need to configure Babel - you do this by means of a preset plugin and a &lt;code class=&quot;highlighter-rouge&quot;&gt;.babelrc&lt;/code&gt; config. Install the ES2015 plugin:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yarn add babel-preset-es2015 --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…then create &lt;code class=&quot;highlighter-rouge&quot;&gt;.babelrc&lt;/code&gt; in the project root, with the following content:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;presets&quot;&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;s2&quot;&gt;&quot;es2015&quot;&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally, amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;webpack.config.js&lt;/code&gt; - tell webpack to apply the configured Babel loader to all JavaScript files, excluding those in &lt;code class=&quot;highlighter-rouge&quot;&gt;node_modules&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;rules&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;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;css$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;use&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;s1&quot;&gt;'style-loader'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'css-loader'&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;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;js$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/node_modules/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;loader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'babel-loader'&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://laracasts.com/series/webpack-for-everyone&quot;&gt;Laracasts - Webpack Video Tutorials&lt;/a&gt; Highly recommended intro to Webpack&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/guides/get-started/&quot;&gt;Webpack 2.x Get Started Guide&lt;/a&gt;
&lt;a href=&quot;https://blog.madewithenvy.com/getting-started-with-webpack-2-ed2b86c68783#.6j14tyqb7&quot;&gt;Good intro to Webpack by Drew Powers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/concepts/loaders/&quot;&gt;webpack 2.x Loaders: Official Docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export&quot;&gt;‘export’ statement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.2ality.com/2014/09/es6-modules-final.html&quot;&gt;ECMAScript 6 Modules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 12 Mar 2017 19:55:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/webpack-configuration-for-javascript-css-and-babel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/webpack-configuration-for-javascript-css-and-babel/</guid>
      </item>
      
    
      
      <item>
        <title>Reduce a Numerically Indexed Array to a Simple Array in PHP</title>
        <description>&lt;p&gt;Reducing a numerically indexed multi-dimensional array to a simple array can be achieved easily by means of combining &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge()&lt;/code&gt; with the ‘splat’ (&lt;code class=&quot;highlighter-rouge&quot;&gt;...&lt;/code&gt;) operator.&lt;/p&gt;

&lt;p&gt;This uses the concept of argument unpacking. It can be really useful if you are starting with a numerically indexed array of arrays and you need to combine them into a single simple array of key-value pairs.&lt;/p&gt;

&lt;h2 id=&quot;starting-point&quot;&gt;Starting Point&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// The Array
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$array&lt;/span&gt; &lt;span class=&quot;o&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;s1&quot;&gt;'key1'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'val1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'key2'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'val2'&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;s1&quot;&gt;'key3'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'val3'&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;s1&quot;&gt;'key4'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'val4'&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;s1&quot;&gt;'key5'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'A'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'B'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bar'&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;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The output of &lt;code class=&quot;highlighter-rouge&quot;&gt;var_dump($array)&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;array (size=4)
  0 =&amp;gt;
    array (size=2)
      'key1' =&amp;gt; string 'val1' (length=4)
      'key2' =&amp;gt; string 'val2' (length=4)
  1 =&amp;gt;
    array (size=1)
      'key3' =&amp;gt; string 'val3' (length=4)
  2 =&amp;gt;
    array (size=1)
      'key4' =&amp;gt; string 'val4' (length=4)
  3 =&amp;gt;
    array (size=1)
      'key5' =&amp;gt;
        array (size=2)
          'A' =&amp;gt; string 'foo' (length=3)
          'B' =&amp;gt; string 'bar' (length=3)&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;operation&quot;&gt;Operation&lt;/h2&gt;
&lt;p&gt;Assuming that you’re using PHP version 5.6 and upwwards (and you should be), you can run the array through &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge()&lt;/code&gt; using the ‘splat’ operator:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$newArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As I understand it (please correct me via a comment if I have this wrong):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge()&lt;/code&gt; accepts an initial array along with a variable list of arrays to merge.&lt;/li&gt;
  &lt;li&gt;Using the ‘splat’ operator tells PHP to unpack the input array into variables.&lt;/li&gt;
  &lt;li&gt;In our case, these variables are arrays, because the staring point was an array of arrays - so we’re passing multiple arrays into &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge()&lt;/code&gt; for processing.&lt;/li&gt;
  &lt;li&gt;Because each variable is a singular array, they’re no longer numerically indexed.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge()&lt;/code&gt; will merge the multiple arrays, and the output array is as associative array, indexed by the keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;result&quot;&gt;Result&lt;/h2&gt;
&lt;p&gt;The output of &lt;code class=&quot;highlighter-rouge&quot;&gt;array_merge(...$array));&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;array (size=5)
  'key1' =&amp;gt; string 'val1' (length=4)
  'key2' =&amp;gt; string 'val2' (length=4)
  'key3' =&amp;gt; string 'val3' (length=4)
  'key4' =&amp;gt; string 'val4' (length=4)
  'key5' =&amp;gt;
    array (size=2)
      'A' =&amp;gt; string 'foo' (length=3)
      'B' =&amp;gt; string 'bar' (length=3)&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;aside-why-splat&quot;&gt;Aside: Why Splat?&lt;/h2&gt;
&lt;p&gt;I don’t know if unpacking arguments is technically an “operation”, so &lt;code class=&quot;highlighter-rouge&quot;&gt;...&lt;/code&gt; may not really be an operator, and it doesn’t look like something that’s gone splat. I’ve read that the symbol for this is in Ruby “*”, and this is where the term originated.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://lornajane.net/posts/2014/php-5-6-and-the-splat-operator&quot;&gt;PHP 5.6 and the ‘splat’ operator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 12 Mar 2017 11:45:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/03/convert-a-numerically-indexed-array-to-a-simple-array-in-php/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/03/convert-a-numerically-indexed-array-to-a-simple-array-in-php/</guid>
      </item>
      
    
      
      <item>
        <title>Using Composer to Manage Specific Version of a Package in a Private Repo</title>
        <description>&lt;p&gt;According to their website, &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; is a dependency manager for PHP. While true, I think this is a bit of an understatement. I’m fairly new to Composer, but it’s revolutionising my workflow.&lt;/p&gt;

&lt;h2 id=&quot;package-in-private-repo&quot;&gt;Package in Private Repo&lt;/h2&gt;
&lt;p&gt;You may need to keep your work in a private VCS repo while it’s still in the early stages of development. It’s easy to set up git repos as public packages on &lt;a href=&quot;https://packagist.org/&quot;&gt;Packagist&lt;/a&gt;, the PHP package repository - but if you need to keep work private you can set Composer up to use a private repo. Here’s a simple example &lt;code class=&quot;highlighter-rouge&quot;&gt;composer.json&lt;/code&gt; for such a use case:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;name&quot;&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;s2&quot;&gt;&quot;project-vendor-name/project-name&quot;&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;nt&quot;&gt;&quot;description&quot;&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;s2&quot;&gt;&quot;Your description&quot;&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;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;library&quot;&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;nt&quot;&gt;&quot;license&quot;&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;s2&quot;&gt;&quot;MIT&quot;&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;nt&quot;&gt;&quot;authors&quot;&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;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;nt&quot;&gt;&quot;name&quot;&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;s2&quot;&gt;&quot;Joe Bloggs&quot;&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;nt&quot;&gt;&quot;email&quot;&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;s2&quot;&gt;&quot;joe@example.com&quot;&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;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;repositories&quot;&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;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;nt&quot;&gt;&quot;type&quot;&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;s2&quot;&gt;&quot;vcs&quot;&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;nt&quot;&gt;&quot;url&quot;&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;s2&quot;&gt;&quot;git@bitbucket.org:vendor-name/private-project.git&quot;&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;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;require&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;vendor-name/private-project&quot;&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;s2&quot;&gt;&quot;dev-master&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This assumes that you’re accessing your private repo by means of SSH keys.&lt;/p&gt;

&lt;h2 id=&quot;use-a-specific-tag-or-commit&quot;&gt;Use a Specific Tag or Commit&lt;/h2&gt;
&lt;p&gt;To lock your project to a specific commit, add a hash to &lt;code class=&quot;highlighter-rouge&quot;&gt;dev-master&lt;/code&gt; followed by a git tag or commit reference:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&quot;vendor-name/private-project&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dev-master#1.0.5&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now when you run &lt;code class=&quot;highlighter-rouge&quot;&gt;composer update&lt;/code&gt;, your project remains locked to a specific version (in this case, tag 1.0.5) of the required package.&lt;/p&gt;

&lt;h2 id=&quot;caveat&quot;&gt;Caveat&lt;/h2&gt;
&lt;p&gt;In the long run, you’re better off creating public Composer packages from your work:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note: This feature has severe technical limitations, as the composer.json metadata will still be read from the branch name you specify before the hash. You should therefore only use this as a temporary solution during development to remediate transient issues, until you can switch to tagged releases. The Composer team does not actively support this feature and will not accept bug reports related to it.
&lt;a href=&quot;https://getcomposer.org/doc/04-schema.md#package-links&quot;&gt;https://getcomposer.org/doc/04-schema.md#package-links&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;[https://getcomposer.org/doc/04-schema.md#package-links](https://getcomposer.org/doc/04-schema.md#package-links)&quot;&gt;Composer Package Links, Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 28 Feb 2017 20:15:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/02/using-composer-to-manage-specific-version-of-a-package-in-a-private-repo/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/02/using-composer-to-manage-specific-version-of-a-package-in-a-private-repo/</guid>
      </item>
      
    
      
      <item>
        <title>Let's Encrypt &amp; Apache on Ubuntu Xenial</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt; is a free, automated, and open Certificate Authority. The service is provided by the &lt;a href=&quot;https://letsencrypt.org/isrg/&quot;&gt;Internet Security Research Group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you’re managing a Virtual Private Server and you want to enable encrypted connection to websites by means of HTTPS(SSL/TLS), Let’s Encrypt is a good choice.&lt;/p&gt;

&lt;h2 id=&quot;lets-encrypt-clientcertbot&quot;&gt;Let’s Encrypt Client/Certbot&lt;/h2&gt;
&lt;p&gt;Certbot is the name of the client that deploys and manages Let’s Encrypt certificates on your server. Confusingly, depending on your system and the version you install, the client may have a different name.&lt;/p&gt;

&lt;h2 id=&quot;certbot-on-ubuntu-1604-xenial&quot;&gt;Certbot on Ubuntu 16.04 Xenial&lt;/h2&gt;
&lt;p&gt;The package is called &lt;code class=&quot;highlighter-rouge&quot;&gt;python-letsencrypt-apache&lt;/code&gt;. To install:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;sudo apt-get install python-letsencrypt-apache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This installs Certbot - but you’ll be using the command &lt;code class=&quot;highlighter-rouge&quot;&gt;letsencrypt&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-new-cert-apache&quot;&gt;Set Up a New Cert: Apache&lt;/h2&gt;
&lt;p&gt;Certbot/Letsencrypt has an Apache plugin that sets up the required Apache configuration. To run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo letsencrypt --apache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This triggers a ncurses dialog that prompts you to select the domains for which you’re enabling SSL. You’ll also be prompted to choose whether or not all resources should be served over HTTPS, or if the site should serve mixed content.&lt;/p&gt;

&lt;p&gt;As part of the cert setup, existing config files in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; are used to set up new configurations for port 443 - and a rewrite rule is added to the exisiting config for port 80 (HTTP traffic). Depending on the selections you make during install, the rewrite rule redirects HTTP traffic to HTTPS.&lt;/p&gt;

&lt;p&gt;I have noticed one glitch in this process. If the existing config file already contains a rewrite rule, the amended config does not include the necessary &lt;code class=&quot;highlighter-rouge&quot;&gt;RewriteEngine on&lt;/code&gt; statement to actually activate the rewrite. You can see an example of this here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@example.com
        &lt;span class=&quot;nc&quot;&gt;DocumentRoot&lt;/span&gt; /var/www/html/example.com/web
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/html/example.com/web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Indexes +FollowSymLinks
                &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all granted
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;wp-login.php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip X.X.X.X
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/html/example.com/path/to/admin-dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip X.X.X.X
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# WordPress Config&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;/var/www/html/example.com/web&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_rewrite.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
                &lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /
                &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^index\.php$ - [L]
                &lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
                &lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
                &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; . /index.php [L]
                &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.error.log
        &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.access.log combined
&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# This line needed to be added manually&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Rewrite rule added by Letsencrypt - in this case, all traffic on&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# this port is sent to the equivalent HTTPS.&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{SERVER_NAME} =example.com [OR]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{SERVER_NAME} =www.example.com
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This isn’t a disaster, but it does mean that you’ll either need to amend the config (and reload the Apache configuration) or amend the root URL in your app (or database) to reference the HTTPS address.&lt;/p&gt;

&lt;p&gt;I always amend the app URL in any case - this means that traffic will be sent straight to HTTPS rather than being redirected.&lt;/p&gt;

&lt;h2 id=&quot;renew-certificate&quot;&gt;Renew Certificate&lt;/h2&gt;
&lt;p&gt;Test renewal:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;letsencrypt renew --dry-run --agree-tos&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If this works, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;letsencrypt renew --agree-tos&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;let’s Encrypt suggest running this script twice per day as a cron job on a random minute in the hour. Certificates are valid for 90 days, and renewal won’t proceed unless the certificate is nearing it’s expiry date.&lt;/p&gt;

&lt;h2 id=&quot;add-a-new-site-to-an-existing-certificate&quot;&gt;Add a New Site to an Existing Certificate&lt;/h2&gt;
&lt;p&gt;To achieve this, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo letsencrypt --apache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…and follow the on-screen instructions. All sites on the server will be listed, and pre-selected for inclusion in the cert. You are then given an option to expand the existing certificate to include the new site. Agree to this and the new site will be added. Don’t forget to check the port 80 Apache config file if redirects are not working.&lt;/p&gt;

&lt;h2 id=&quot;common-name&quot;&gt;Common Name&lt;/h2&gt;
&lt;p&gt;You may end up with the wrong domain name as the common name attached to the certificate. You can force this by running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;sudo letsencrypt --apache -d primary-domain.com -d www.primary-domain.com -d secondary-domain.com -d www.secondary-domain.com --force-renewal&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will result in a certifcate with the common name set to the first domain (in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;primary-domain.com&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;moving-servers-client-confusion&quot;&gt;Moving Servers: Client Confusion!&lt;/h2&gt;
&lt;p&gt;During a recent server upgrade, I moved Let’s Encrypt certificates to the new server. &lt;a href=&quot;/2016/12/moving-site-to-new-server-with-letsencrypt-certificates/&quot;&gt;Description here&lt;/a&gt;. This is a fairly straightforward process, and allows sites to be migrated without downtime.&lt;/p&gt;

&lt;p&gt;However, I experienced a problem when renewing the Certificate.&lt;/p&gt;

&lt;p&gt;The old server (Ubuntu 14.04) was running a version of Certbot cloned from the GitHub repo (which is actually a pretty good option - it self updates every time you run it). On the new server (Ubuntu 16.04), I followed the Certbot install instructions for Ubuntu 16.04 as outlined &lt;a href=&quot;https://certbot.eff.org/#ubuntuxenial-apache&quot;&gt;here&lt;/a&gt;. This caused problems because the config file (created on the original server) was actually created by a newer version of Certbot than that found in the Ubuntu repos for 16.04. The OLD server had newer software than the NEW server.&lt;/p&gt;

&lt;p&gt;The error:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;KeyError: &lt;span class=&quot;s1&quot;&gt;'server'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The fix:
You could revoke the cert, remove the client, install Certbot as before and re-install the certificates. In other words, take off and nuke it from orbit (I always wanted to use that expression in a blog post). Alternatively append the following line to your renewal config files (see: &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt/renewal&lt;/code&gt;):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;server &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; https://acme-v01.api.letsencrypt.org/directory&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you have a &lt;code class=&quot;highlighter-rouge&quot;&gt;[[webroot_map]]&lt;/code&gt; entry in the renewal config file, add the server line above that.&lt;/p&gt;

&lt;p&gt;Kudos to &lt;a href=&quot;https://github.com/bmw&quot;&gt;Brad Warren&lt;/a&gt; for sharing this solution (ref below) in the Certbot issue tracker.&lt;/p&gt;

&lt;h2 id=&quot;remove-cert-the-nuclear-solution&quot;&gt;Remove Cert: The Nuclear Solution&lt;/h2&gt;
&lt;p&gt;Move into &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt&lt;/code&gt; and remove everything apart from the &lt;code class=&quot;highlighter-rouge&quot;&gt;accounts&lt;/code&gt; directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /etc/letsencrypt
sudo rm -rf archive csr keys live options-ssl-apache.conf renewal&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Disable the SSL enabled sites by running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2dissite example.com-le-ssl.conf
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Remove all Apache ssl config files from &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available&lt;/code&gt; and reload Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /etc/apache2/sites-available
sudo rm example.com-le-ssl.conf &lt;span class=&quot;c&quot;&gt;# etc&lt;/span&gt;
sudo service apache2 reload&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note: Unless you’ve removed the redirect in the port 80 virtual host directive, and/or updated your app’s home URL, your site will now be broken.&lt;/strong&gt; Take care. You should temporarily switch the site to HTTP whilst re-issuing the certificate - I’m assuming you know how to do that.&lt;/p&gt;

&lt;p&gt;Run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo letsencrypt --apache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will reissue the certificate.&lt;/p&gt;

&lt;p&gt;This is very much a nuclear option - there are better ways to use the letsencrypt client to amend certificates and settings.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Certbot Issue, GitHub: &lt;a href=&quot;https://github.com/certbot/certbot/issues/2750#issuecomment-238983818&quot;&gt;Error with renewal conf files that no longer have a “server” entry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 25 Feb 2017 11:37:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/02/letsencrypt-ubuntu-xenial/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/02/letsencrypt-ubuntu-xenial/</guid>
      </item>
      
    
      
      <item>
        <title>Connect Bitbucket with Slack to Receive Notifications</title>
        <description>&lt;p&gt;Receive Slack notifications when activity occurs on a Bitbucket repo. This is a useful way for team members to monitor progress.&lt;/p&gt;

&lt;p&gt;This assumes that you’ve added the Bitbucket app to Slack.&lt;/p&gt;

&lt;h2 id=&quot;slack&quot;&gt;Slack&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Go to https://YOURTEAM.slack.com/apps/manage&lt;/li&gt;
  &lt;li&gt;Select Bitbucket&lt;/li&gt;
  &lt;li&gt;“Add Configuration”&lt;/li&gt;
  &lt;li&gt;Choose channel, select “Add Bitbucket Integration”&lt;/li&gt;
  &lt;li&gt;Copy the provided webhook - this will be required in the steps outlined below&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;bitbucket&quot;&gt;Bitbucket&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Go to repo&lt;/li&gt;
  &lt;li&gt;Select “Settings” in left navigation&lt;/li&gt;
  &lt;li&gt;“Workflow” section, click “Add webhook” button&lt;/li&gt;
  &lt;li&gt;Give the webhook a unique name and paste in the hook generated by Slack as described above&lt;/li&gt;
  &lt;li&gt;Select “Choose from a full list of triggers” for additional utility&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 30 Jan 2017 09:40:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/01/connect-bitbucket-with-slack-to-receive-notifications/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/01/connect-bitbucket-with-slack-to-receive-notifications/</guid>
      </item>
      
    
      
      <item>
        <title>Gitignore Directory Contents</title>
        <description>&lt;p&gt;You may need to gitignore the contents of a directory, whilst including the empty directory in version control.&lt;/p&gt;

&lt;p&gt;For example, you have a &lt;code class=&quot;highlighter-rouge&quot;&gt;config&lt;/code&gt; directory that contains config files that are app specific. It may useful to include the &lt;code class=&quot;highlighter-rouge&quot;&gt;config&lt;/code&gt; directory, so you can easily see where to place config files.&lt;/p&gt;

&lt;p&gt;To achive this, add a &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitkeep&lt;/code&gt; file to the directory. Then in the repository’s &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-git&quot; data-lang=&quot;git&quot;&gt;config/*
# exception to the rule
!config/.gitkeep&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 25 Jan 2017 16:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/01/gitignore-directory-contents/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/01/gitignore-directory-contents/</guid>
      </item>
      
    
      
      <item>
        <title>MixItUp JavaScript Filter with Bootstrap Dropdown Toggle</title>
        <description>&lt;p&gt;MixItUp is a dependency-free JavaScript library for animated filtering, sorting, insertion, removal etc:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.kunkalabs.com/mixitup/&quot;&gt;MixItUp Homepage&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/patrickkunka/mixitup&quot;&gt;MixItUp GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MixItUp is a pretty good library - easy to build nice filters. You need to buy the commercial license if you’re using it on a commercial project.&lt;/p&gt;

&lt;h2 id=&quot;bootstrap-conflict&quot;&gt;Bootstrap Conflict&lt;/h2&gt;
&lt;p&gt;There is a slight conflict with Bootstrap 3 dropdown elements. If you’re using a Bootstrap dropdown to display a list of filter elements, a MixItUp control is triggered when you click the dropdown. The &lt;code class=&quot;highlighter-rouge&quot;&gt;data-toggle&lt;/code&gt; of the Bootstrap dropdown interferes wityh MixItUp This will probably hide all the elements that you’re trying to filter, as this element won’t have the required &lt;code class=&quot;highlighter-rouge&quot;&gt;data-filter&lt;/code&gt; attribute.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;For MixItUp &amp;gt;= 3.1, the solution is to specify the control element in the configuration object:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;mixitup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;container&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;na&quot;&gt;selectors&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;na&quot;&gt;control&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'[data-mixitup-control]'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;… you then add the &lt;code class=&quot;highlighter-rouge&quot;&gt;data-mixitup-control&lt;/code&gt; attribute to the filter controls.&lt;/p&gt;

&lt;h2 id=&quot;jsfiddle&quot;&gt;JSFiddle&lt;/h2&gt;
&lt;script async=&quot;&quot; src=&quot;//jsfiddle.net/davidcw/bL7jchLs/embed/&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/patrickkunka/mixitup/issues/268&quot;&gt;GitHub issue with solution&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 25 Jan 2017 14:39:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/01/mixitup-javascript-filter/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/01/mixitup-javascript-filter/</guid>
      </item>
      
    
      
      <item>
        <title>Apache Directives in Config vs .htaccess</title>
        <description>&lt;p&gt;Apache allows configuration rules to be overridden at the directory level by means of distributed configuration files. These files are usually called  &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt;, but the file name can be customised. Directives placed in &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; apply to the directory that contains the file, and changes to &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; have immediate effect for that directory. However, this can be wasteful of resources - &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files are read on every request.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In general, you should only use .htaccess files when you don’t have access to the main server configuration file…&lt;/p&gt;

  &lt;p&gt;….htaccess files should be used in a case where the content providers need to make configuration changes to the server on a per-directory basis, but do not have root access on the server system…&lt;/p&gt;

  &lt;p&gt;…However, in general, use of .htaccess files should be avoided when possible. Any configuration that you would consider putting in a .htaccess file, can just as effectively be made in a &lt;Directory&gt; section in your main server configuration file.&lt;/Directory&gt;&lt;/p&gt;

  &lt;p&gt;— &lt;a href=&quot;http://httpd.apache.org/docs/current/howto/htaccess.html#page-header&quot;&gt;Apache Docs, .htaccess&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re managing sites on a VPS, there’s no need to use distributed configuration files. I think I personally became conditioned to them from managing sites on shared hosting, with no root access.&lt;/p&gt;

&lt;p&gt;Because of this, I’ve been moving Apache rewrite rules and access restrictions out of &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files and into virtual host configs.&lt;/p&gt;

&lt;h2 id=&quot;global-rules&quot;&gt;Global Rules&lt;/h2&gt;
&lt;p&gt;In some cases, the rules that might have gone into a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file can be applied at a server level - for example, preventing access to &lt;code class=&quot;highlighter-rouge&quot;&gt;.git&lt;/code&gt; directories and restricting access to config files (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;) is probably best achieved by adding appropriate rules to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/conf-enabled/security.conf&lt;/code&gt; (the Ubuntu apache2 security config file). If you’re blocking access to these files in one directory, the chances are that you’ll want to apply this to the whole server.&lt;/p&gt;

&lt;h2 id=&quot;per-directory-rules-wordpress&quot;&gt;Per-Directory Rules: WordPress&lt;/h2&gt;
&lt;p&gt;The normal WordPress rewrite block can be easily added to a virtual host config. This allows you to disallow overriding at the directory level which speeds things up.&lt;/p&gt;

&lt;p&gt;The following sections contrast how to achieve the same effect with a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file and a virtual host configuration. In this case, a set of WordPress rewrites are needed, along with some restrictions based on IP address.&lt;/p&gt;

&lt;h2 id=&quot;typical-wordpress-htaccess-file-production-site&quot;&gt;Typical WordPress .htaccess File: Production Site&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file is placed in the site document root. If the file is writeable by WordPress, WP will generate the config block between &lt;code class=&quot;highlighter-rouge&quot;&gt;# BEGIN WordPress&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;# END WordPress&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file has an additional rule that restricts access to the main site login by IP.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Restrict access to WordPress login page by IP&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See: http://httpd.apache.org/docs/2.4/mod/core.html#files&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;wp-login.php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip x.x.x.x y.y.y.y
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# BEGIN WordPress&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_rewrite.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^index\.php$ - [L]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; . /index.php [L]
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# END WordPress&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;apache-vhost-configuration-with-wordpress-specific-rules&quot;&gt;Apache vHost Configuration with WordPress Specific Rules&lt;/h2&gt;
&lt;p&gt;To achieve the same thing without use of &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt;, amend the site virtual host config file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_ssl.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:443&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@example.com
        &lt;span class=&quot;nc&quot;&gt;DocumentRoot&lt;/span&gt; /var/www/html/example.com/web
        &lt;span class=&quot;c&quot;&gt;# Disallow overrides (.htaccess) in the document root&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/html/example.com/web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Indexes +FollowSymLinks
                &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all granted
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# Restrict access to wp-login.php - space separated list of allowed IPs&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;wp-login.php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip x.x.x.x y.y.y.y
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# Restrict access to the site admin area by IP&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/html/example.com/web/wp/wp-admin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;None&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip x.x.x.x y.y.y.y
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# WordPress Config - this must be placed in a &amp;lt;Directory&amp;gt; block&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;/var/www/html/example.com/web&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_rewrite.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
                &lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /
                &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^index\.php$ - [L]
                &lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
                &lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
                &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; . /index.php [L]
                &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# Set custom logs&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.error.log
        &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.access.log combined
        &lt;span class=&quot;c&quot;&gt;# SSL cert details (LetsEncrypt)&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;SSLCertificateFile&lt;/span&gt; /etc/letsencrypt/live/example.com/fullchain.pem
        &lt;span class=&quot;nc&quot;&gt;SSLCertificateKeyFile&lt;/span&gt; /etc/letsencrypt/live/example.com/privkey.pem
        &lt;span class=&quot;nc&quot;&gt;Include&lt;/span&gt; /etc/letsencrypt/options-ssl-apache.conf
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;typical-htaccess-rules-for-private-staging-site&quot;&gt;Typical .htaccess Rules for Private Staging Site&lt;/h2&gt;
&lt;p&gt;This &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file is for a site that is in a sub-directory of the domain document root. For example: &lt;code class=&quot;highlighter-rouge&quot;&gt;testdomain.com/testsite&lt;/code&gt;. This is often a convenient way of handling staging websites.&lt;/p&gt;

&lt;p&gt;In this case, the main Apache vHost configuration for the “parent” domain needs to allow override by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt;. This is achieved by setting the &lt;code class=&quot;highlighter-rouge&quot;&gt;AllowOverride&lt;/code&gt; directive to “All” in the virtual host config file. When this directive is set to None and AllowOverrideList is set to None, &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files are completely ignored. In this case, the server will not even attempt to read &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; files in the filesystem.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Full block - private. This is a staging site!&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;RequireAll&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip x.x.x.x y.y.y.y
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;RequireAll&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Restrict access to WordPress login page by IP&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See: http://httpd.apache.org/docs/2.4/mod/core.html#files&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;wp-login.php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip x.x.x.x y.y.y.y
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# BEGIN WordPress&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_rewrite.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /testsite/
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^index\.php$ - [L]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; . /testsite/index.php [L]
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# END WordPress&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;reload-apache-configs&quot;&gt;Reload Apache Configs&lt;/h2&gt;
&lt;p&gt;If you move your local config into virtual host configs, any changes you make will not take effect until you reload Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo /etc/init.d/apache2 reload

&lt;span class=&quot;c&quot;&gt;# or use `force-reload`, an alias for the same command:&lt;/span&gt;
sudo /etc/init.d/apache2 force-reload&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 10 Jan 2017 14:53:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/01/apache-directives-in-config-vs-htaccess/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/01/apache-directives-in-config-vs-htaccess/</guid>
      </item>
      
    
      
      <item>
        <title>Convert ACF Fields Registered by PHP to Importable JSON Format</title>
        <description>&lt;p&gt;When using the WordPress Advanced Custom Fields plugin, you may need to switch between PHP registered custom fields and JSON registered fields.&lt;/p&gt;

&lt;h2 id=&quot;use-case&quot;&gt;Use Case&lt;/h2&gt;
&lt;p&gt;In older projects we registered ACF fields by importing to PHP. This is good for the deployed site - the fields load quicker, and users can’t amend the fields.&lt;/p&gt;

&lt;p&gt;This can be problematic if you import a production database into a local development environment. The fields are not registered in the production database. When you import it, you no longer have access to the fields in the ACF GUI. The fields still exist (they are registered by PHP functions), but you can’t use the nifty ACF interface to edit them.&lt;/p&gt;

&lt;p&gt;Because of this we have switched to ACFs local JSON option. ACF writes the field registration data in JSON format to a server-writable directory (&lt;code class=&quot;highlighter-rouge&quot;&gt;acf-json&lt;/code&gt;, unless you override the default) in the theme root. You end up with a separate JSON file for each field group. The JSON configuration files can go into your version control system. You can deploy to staging or production, and if you accidentally delete files in your dev environment (for example, if you import a database) you can easily re-sync the JSON files to have them show up in the ACF GUI again.&lt;/p&gt;

&lt;p&gt;If you have your fields registered by PHP (not in the database), how do you switch to the local JSON workflow?&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a JSON configuration file that can be read by the ACF “Import” function - i.e. mimic the output of the ACF “Export” function&lt;/li&gt;
  &lt;li&gt;Create &lt;code class=&quot;highlighter-rouge&quot;&gt;acf-json&lt;/code&gt; in your theme root and run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chown www-data acf-json&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Import the JSON file to ACF&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;creating-the-json-file-for-import&quot;&gt;Creating the JSON File for Import&lt;/h2&gt;
&lt;p&gt;The following quick and dirty method is suitable for a local development environment:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Drop the code below into a suitable template&lt;/li&gt;
  &lt;li&gt;Create a suitable config file - &lt;code class=&quot;highlighter-rouge&quot;&gt;touch acf-import.json&lt;/code&gt; and make it server-writable&lt;/li&gt;
  &lt;li&gt;Hit the page template in your browser - you’ll see the JSON data output, and this will be written to the config file&lt;/li&gt;
  &lt;li&gt;Import the config file: within the ACF “Tools” &amp;gt; “Import Field Groups” interface, select the file and click import&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The field configurations are now held in the local database, and will be saved in the &lt;code class=&quot;highlighter-rouge&quot;&gt;acf-json&lt;/code&gt; directory.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$groups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acf_get_local_field_groups&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$groups&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$group&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;c1&quot;&gt;// Fetch the fields for the given group key
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acf_get_local_fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'key'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Remove unecessary key value pair with key &quot;ID&quot;
&lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'ID'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Add the fields as an array to the group
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'fields'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$fields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Add this group to the main array
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$group&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;nv&quot;&gt;$json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON_PRETTY_PRINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Optional - echo the JSON data to the page
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;/pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Write output to file for easy import into ACF.
// The file must be writable by the server process. In this case, the file is located in
// the current theme directory.
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_template_directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/acf-import.json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;file_put_contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sat, 07 Jan 2017 18:39:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2017/01/convert-acf-fields-registered-by-php-to-importable-json-format/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2017/01/convert-acf-fields-registered-by-php-to-importable-json-format/</guid>
      </item>
      
    
      
      <item>
        <title>Jekyll Deploy Methodology</title>
        <description>&lt;p&gt;This post outlines a simple and secure method for deploying a Jekyll site to a server/VPS by means of SSH using Grunt and Bash.&lt;/p&gt;

&lt;p&gt;The objective is to deploy a website by means of a Grunt task without exposing senstive information (SSH port, server IP address, username etc) in the Gruntfile. This allows the Gruntfile to be added to your VCS.&lt;/p&gt;

&lt;p&gt;This is achieved by running a custom Bash script, which is executed from within Grunt.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-grunt-exec&quot;&gt;Setting up Grunt Exec&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/jharding/grunt-exec&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-exec&lt;/code&gt;&lt;/a&gt; plugin allows shell commands to be executed from within Grunt.&lt;/p&gt;

&lt;p&gt;Install &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-exec&lt;/code&gt; with Yarn:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;yarn add grunt-exec --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…&lt;strong&gt;or&lt;/strong&gt; install &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-exec&lt;/code&gt; with NPM:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;npm install grunt-exec --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The configuration for &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-exec&lt;/code&gt; might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/* /grunt-config/exec.js */&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build&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;na&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bundle exec jekyll build'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;dev&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;na&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bundle exec jekyll build --watch --config _config.yml,_config_dev.yml --drafts'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;serve&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;na&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bundle exec jekyll serve --watch'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;deploy&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;na&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'deploy-my-website'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that this config is separated out into a separate file, which requires the &lt;a href=&quot;https://github.com/creynders/load-grunt-configs&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;load-grunt-configs&lt;/code&gt; plugin&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-gruntfile&quot;&gt;The Gruntfile&lt;/h2&gt;
&lt;p&gt;Your deploy tasks can now be defined in the project &lt;code class=&quot;highlighter-rouge&quot;&gt;Gruntfile.js&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;grunt&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;c1&quot;&gt;// Define scope for `load-grunt-tasks` package.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scope&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;s1&quot;&gt;'devDependencies'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'dependencies'&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;c1&quot;&gt;// Define location of config files for `load-grunt-configs`.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;config&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;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;grunt-config/*.js&quot;&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;c1&quot;&gt;// Require `load-grunt-configs` with the defined options.&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;configs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'load-grunt-configs'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Load the various task configuration files.&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;initConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;configs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Auto-load tasks.&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'load-grunt-tasks'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Register tasks&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'default'&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;s1&quot;&gt;'sass:development'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'concat:public'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'uglify:public'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'exec:dev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'watch'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'deploy'&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;s1&quot;&gt;'exec:build'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'exec:deploy'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now from within your project directory running &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt deploy&lt;/code&gt; will run the &lt;code class=&quot;highlighter-rouge&quot;&gt;exec:build&lt;/code&gt; task (&lt;code class=&quot;highlighter-rouge&quot;&gt;bundle exec jekyll build&lt;/code&gt;), followed by the &lt;code class=&quot;highlighter-rouge&quot;&gt;exec:deploy&lt;/code&gt; task.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;exec:deploy&lt;/code&gt; task runs a BASH script called &lt;code class=&quot;highlighter-rouge&quot;&gt;deploy-my-website&lt;/code&gt; - which should be held locally, outside your version control system.&lt;/p&gt;

&lt;h2 id=&quot;bash-deploy-script&quot;&gt;BASH Deploy Script&lt;/h2&gt;
&lt;p&gt;I like to organise deploy scripts into a dedicated directory, creating symlinks to the files from with my &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin&lt;/code&gt; directory (or somewhere within your &lt;code class=&quot;highlighter-rouge&quot;&gt;$PATH&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The deploy script should be executable:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Create symlink&lt;/span&gt;
sudo ln -s ~/deploy-scripts/deploy-my-website /usr/local/bin

&lt;span class=&quot;c&quot;&gt;# Make executable&lt;/span&gt;
sudo chmod +x ~/deploy-scripts/deploy-my-website&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The deploy script utilises Rsync to copy files across to the server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# deploy-my-website&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Deploy to example.com&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4321                                           &lt;span class=&quot;c&quot;&gt;# Custom port for SSH&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;USERNAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;my-user                                    &lt;span class=&quot;c&quot;&gt;# Username for the server&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SERVER_IP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;XXX.XXX.XXX.XXX&quot;&lt;/span&gt;                         &lt;span class=&quot;c&quot;&gt;# Server IP address&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;REMOTE_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/var/www/html/example.com/public_html&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Server path&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;LOCAL_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/var/www/html/example.com/_site/&quot;&lt;/span&gt;       &lt;span class=&quot;c&quot;&gt;# Local path&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SITENAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My website&quot;&lt;/span&gt;                               &lt;span class=&quot;c&quot;&gt;# Site name&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;deploy&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Rsync options&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;--progress -a -v -rz --checksum --delete -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    rsync &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LOCAL_PATH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;USERNAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;@&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SERVER_IP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REMOTE_PATH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Deploying &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SITENAME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; to PRODUCTION...&quot;&lt;/span&gt;

deploy;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In our case, SSH is configured to only allow connection by means of &lt;a href=&quot;https://wiki.archlinux.org/index.php/SSH_keys&quot;&gt;SSH Keys&lt;/a&gt; - Public Key Cryptography/Challenge Response Authemtication. This makes the deployment process very secure - the local private key (passphrase protected for extra security) is necessary to establish the connection to the server.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jharding/grunt-exec&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-exec&lt;/code&gt; plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 30 Dec 2016 15:02:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/12/jekyll-deploy-methodology/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/12/jekyll-deploy-methodology/</guid>
      </item>
      
    
      
      <item>
        <title>Moving Site to New Server with Letsencrypt Certificates</title>
        <description>&lt;p&gt;When moving a site to a new server, you can migrate the LetsEncrypt certificates. You need to be careful that the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt&lt;/code&gt; directory is installed on the new server with the proper ownerships and permissions.&lt;/p&gt;

&lt;p&gt;This guide is intended for Ubuntu Xenial 16.04.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Because of the nature of the files (security certificates), they should be transferred by means of a secure protocol such as SSH.&lt;/p&gt;

&lt;h2 id=&quot;source-server&quot;&gt;Source Server&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/letsencrypt&lt;/code&gt; directory on the original server needs to be copied to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc&lt;/code&gt; on the new server.&lt;/p&gt;

&lt;p&gt;This is a bit tricky, because the directory is owned by root - you can’t just rsync in and pull down the directory. You could add rsync to the sudo group on the source server &lt;a href=&quot;https://ubuntuforums.org/showthread.php?t=2264306&amp;amp;p=13223227#post13223227&quot;&gt;as described here&lt;/a&gt; (Note: I’ve not tried this) but this makes me nervous due to potential mistakes/mischief.&lt;/p&gt;

&lt;p&gt;Instead, sudo rsync the directory to a suitable location and set your user as the owner of the copy. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Note -p is added&lt;/span&gt;
sudo rsync -az -p --progress /etc/letsencrypt ~/
sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; ~/letsencrypt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;local-machine&quot;&gt;Local Machine&lt;/h2&gt;
&lt;p&gt;Pull the directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Assumes SSH connection over port 4321&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# replace $REMOTEUSER and $SOURCE_IP with suitable values&lt;/span&gt;
rsync -az -p -e &lt;span class=&quot;s1&quot;&gt;'ssh -p 4321'&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$REMOTEUSER&lt;/span&gt;@&lt;span class=&quot;nv&quot;&gt;$SOURCE_IP&lt;/span&gt;:~/letsencrypt ~/servers/staging&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now push this directory to the new location:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Assumes connection over port 4221&lt;/span&gt;
rsync -az -p -e &lt;span class=&quot;s1&quot;&gt;'ssh -p 4221'&lt;/span&gt; ~/servers/staging/letsencrypt &lt;span class=&quot;nv&quot;&gt;$NEW_REMOTE_USER&lt;/span&gt;@&lt;span class=&quot;nv&quot;&gt;$DESTINATION_IP&lt;/span&gt;:&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will copy the &lt;code class=&quot;highlighter-rouge&quot;&gt;letsencrypt&lt;/code&gt; directory to your users home directory on the destination server.&lt;/p&gt;

&lt;h2 id=&quot;destination-server&quot;&gt;Destination Server&lt;/h2&gt;
&lt;p&gt;Move the directory into place and set proper ownership:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Lack of trailing slash on source will cause the directory to be created on the destination directory&lt;/span&gt;
sudo rsync -az --progress ~/letsencrypt /etc
sudo chown -R root:root /etc/letsencrypt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;firewall-notes-https&quot;&gt;Firewall Notes: HTTPS&lt;/h2&gt;
&lt;p&gt;Your firewall needs to open port 443.
To check open ports, use &lt;code class=&quot;highlighter-rouge&quot;&gt;netstat&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;netstat -tnl

&lt;span class=&quot;c&quot;&gt;# Typical output - shows that port 443 is open&lt;/span&gt;
Active Internet connections &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;only servers&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:25            0.0.0.0:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;               LISTEN
tcp        0      0 127.0.0.1:3306          0.0.0.0:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;               LISTEN
tcp        0      0 0.0.0.0:4321            0.0.0.0:&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;               LISTEN
tcp6       0      0 ::1:25                  :::&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;                    LISTEN
tcp6       0      0 :::443                  :::&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;                    LISTEN
tcp6       0      0 :::4321                 :::&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;                    LISTEN
tcp6       0      0 :::80                   :::&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;                    LISTEN&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You need to have a service listening on a port for the port to be determined “open”. This initially confused me - I hadn’t yet set up Apache for SSL (i.e. to listen on 443), and the &lt;code class=&quot;highlighter-rouge&quot;&gt;netstat&lt;/code&gt; output did not show an entry for 443 - you might assume that your firewall is blocking the port, when you just do not have any services listening on 443.&lt;/p&gt;

&lt;h2 id=&quot;enable-ssl-apache&quot;&gt;Enable SSL: Apache&lt;/h2&gt;
&lt;p&gt;The Apache ssl module needs to be enabled for SSL/HTTPS to work:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod ssl
&lt;span class=&quot;c&quot;&gt;# Restart Apache:&lt;/span&gt;
sudo service apache2 reload&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;note-re-rsync--p&quot;&gt;Note re: rsync -p&lt;/h2&gt;
&lt;p&gt;As far as I’m aware, the &lt;code class=&quot;highlighter-rouge&quot;&gt;-p&lt;/code&gt; option is implicit in &lt;code class=&quot;highlighter-rouge&quot;&gt;-a&lt;/code&gt;, which is equivalent to &lt;code class=&quot;highlighter-rouge&quot;&gt;-rlptgoD&lt;/code&gt; - so probably &lt;code class=&quot;highlighter-rouge&quot;&gt;-p&lt;/code&gt; is unecessary. However, I had a couple of transfers that did not preserve permissions - maybe due to an error on my part, but no harm to include &lt;code class=&quot;highlighter-rouge&quot;&gt;-p&lt;/code&gt;. There seems to be quite a subtle set of permissions on the &lt;code class=&quot;highlighter-rouge&quot;&gt;letsencrypt&lt;/code&gt; files, so messing them up is not a trivial thing.&lt;/p&gt;
</description>
        <pubDate>Mon, 19 Dec 2016 19:31:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/12/moving-site-to-new-server-with-letsencrypt-certificates/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/12/moving-site-to-new-server-with-letsencrypt-certificates/</guid>
      </item>
      
    
      
      <item>
        <title>Overriding Fail2Ban Settings</title>
        <description>&lt;p&gt;Fail2ban takes config data from files in the following order of precedence:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.d/*.conf&lt;/code&gt;, alphabetically&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.local&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.d/*.local&lt;/code&gt;, alphabetically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Don’t amend &lt;code class=&quot;highlighter-rouge&quot;&gt;*.conf&lt;/code&gt; files&lt;/strong&gt; - which are distributed by Fail2Ban, and may be overwritten if Fail2Ban is upgraded. Instead, make customizations in &lt;code class=&quot;highlighter-rouge&quot;&gt;*.local&lt;/code&gt; files. For example, if you  would  like  to  enable the &lt;code class=&quot;highlighter-rouge&quot;&gt;[ssh-iptables-ipset]&lt;/code&gt; jail specified in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt;, create &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.local&lt;/code&gt; and add the following lines:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# /etc/fail2ban/jail.local&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ssh-iptables-ipset]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You only need to specify settings that you would like to change - the rest of  the configuration is taken from the corresponding &lt;code class=&quot;highlighter-rouge&quot;&gt;.conf&lt;/code&gt; file which is parsed first.&lt;/p&gt;

&lt;h2 id=&quot;reference-content-of-etcfail2banjailconf&quot;&gt;Reference: Content of &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;It’s handy to have this available on a web page - it saves opening and closing the parent config on the server you’re working on. This is the config for  Fail2Ban v0.9.3&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# WARNING: heavily refactored in 0.9.0 release.  Please review and&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#          customize settings for your setup.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Changes:  in most of the cases you should not modify this&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#           file, but provide customizations in jail.local file,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#           or separate .conf files under jail.d/ directory, e.g.:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# HOW TO ACTIVATE JAILS:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# YOU SHOULD NOT MODIFY THIS FILE.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# It will probably be overwritten or improved in a distribution update.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Provide customizations in a jail.local file or a jail.d/customisation.local.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# For example to change the default bantime for all jails and to enable the&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ssh-iptables jail the following (uncommented) would appear in the .local file.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See man 5 jail.conf for details.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [DEFAULT]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# bantime = 3600&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [sshd]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# enabled = true&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See jail.conf(5) man page for more information&lt;/span&gt;



&lt;span class=&quot;c&quot;&gt;# Comments: use '#' for comment lines and ';' (following a space) for inline comments&lt;/span&gt;


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;INCLUDES]

&lt;span class=&quot;c&quot;&gt;#before = paths-distro.conf&lt;/span&gt;
before &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; paths-debian.conf

&lt;span class=&quot;c&quot;&gt;# The DEFAULT allows a global definition of the options. They can be overridden&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# in each jail afterwards.&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;DEFAULT]

&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# MISCELLANEOUS OPTIONS&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# &quot;ignoreip&quot; can be an IP address, a CIDR mask or a DNS host. Fail2ban will not&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ban a host which matches an address in this list. Several addresses can be&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# defined using space separator.&lt;/span&gt;
ignoreip &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 127.0.0.1/8

&lt;span class=&quot;c&quot;&gt;# External command that will take an tagged arguments to ignore, e.g. &amp;lt;ip&amp;gt;,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# and return true if the IP is to be ignored. False otherwise.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ignorecommand = /path/to/command &amp;lt;ip&amp;gt;&lt;/span&gt;
ignorecommand &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# &quot;bantime&quot; is the number of seconds that a host is banned.&lt;/span&gt;
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 600

&lt;span class=&quot;c&quot;&gt;# A host is banned if it has generated &quot;maxretry&quot; during the last &quot;findtime&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# seconds.&lt;/span&gt;
findtime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 600

&lt;span class=&quot;c&quot;&gt;# &quot;maxretry&quot; is the number of failures before a host get banned.&lt;/span&gt;
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5

&lt;span class=&quot;c&quot;&gt;# &quot;backend&quot; specifies the backend used to get files modification.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Available options are &quot;pyinotify&quot;, &quot;gamin&quot;, &quot;polling&quot;, &quot;systemd&quot; and &quot;auto&quot;.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This option can be overridden in each jail as well.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# pyinotify: requires pyinotify (a file alteration monitor) to be installed.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#              If pyinotify is not installed, Fail2ban will use auto.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# gamin:     requires Gamin (a file alteration monitor) to be installed.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#              If Gamin is not installed, Fail2ban will use auto.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# polling:   uses a polling algorithm which does not require external libraries.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# systemd:   uses systemd python library to access the systemd journal.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#              Specifying &quot;logpath&quot; is not valid for this backend.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#              See &quot;journalmatch&quot; in the jails associated filter config&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# auto:      will try to use the following backends, in order:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#              pyinotify, gamin, polling.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Note: if systemd backend is choses as the default but you enable a jail&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#       for which logs are present only in its own log files, specify some other&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#       backend for that jail (e.g. polling) and provide empty value for&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#       journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200&lt;/span&gt;
backend &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; auto

&lt;span class=&quot;c&quot;&gt;# &quot;usedns&quot; specifies if jails should trust hostnames in logs,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   warn when DNS lookups are performed, or ignore all hostnames in logs&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# yes:   if a hostname is encountered, a DNS lookup will be performed.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# warn:  if a hostname is encountered, a DNS lookup will be performed,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#        but it will be logged as a warning.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# no:    if a hostname is encountered, will not be used for banning,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#        but it will be logged as info.&lt;/span&gt;
usedns &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; warn

&lt;span class=&quot;c&quot;&gt;# &quot;logencoding&quot; specifies the encoding of the log files handled by the jail&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   This is used to decode the lines from the log file.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   Typical examples:  &quot;ascii&quot;, &quot;utf-8&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   auto:   will use the system locale setting&lt;/span&gt;
logencoding &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; auto

&lt;span class=&quot;c&quot;&gt;# &quot;enabled&quot; enables the jails.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  By default all jails are disabled, and it should stay this way.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  Enable only relevant to your setup jails in your .local or jail.d/*.conf&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# true:  jail will be enabled and log files will get monitored for changes&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# false: jail is not enabled&lt;/span&gt;
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# &quot;filter&quot; defines the filter to use by the jail.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  By default jails have names matching their filter name&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
filter &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ACTIONS&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Some options used for actions&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Destination email address used solely for the interpolations in&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# jail.{conf,local,d/*} configuration files.&lt;/span&gt;
destemail &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; root@localhost

&lt;span class=&quot;c&quot;&gt;# Sender email address used solely for some actions&lt;/span&gt;
sender &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; root@localhost

&lt;span class=&quot;c&quot;&gt;# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# mailing. Change mta configuration parameter to mail if you want to&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# revert to conventional 'mail'.&lt;/span&gt;
mta &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; sendmail

&lt;span class=&quot;c&quot;&gt;# Default protocol&lt;/span&gt;
protocol &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; tcp

&lt;span class=&quot;c&quot;&gt;# Specify chain where jumps would need to be added in iptables-* actions&lt;/span&gt;
chain &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; INPUT

&lt;span class=&quot;c&quot;&gt;# Ports to be banned&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Usually should be overridden in a particular jail&lt;/span&gt;
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0:65535

&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Action shortcuts. To be used to define action parameter&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Default banning action (e.g. iptables, iptables-new,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iptables-multiport, shorewall, etc) It is used to define&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# action_* variables. Can be overridden globally or per&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# section within jail.local file&lt;/span&gt;
banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-multiport

&lt;span class=&quot;c&quot;&gt;# The simplest action to take: ban only&lt;/span&gt;
action_ &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;bantime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(bantime)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(protocol)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ban &amp;amp; send an e-mail with whois report to the destemail.&lt;/span&gt;
action_mw &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;bantime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(bantime)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(protocol)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
            %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-whois[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(destemail)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(protocol)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ban &amp;amp; send an e-mail with whois report and relevant log lines&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to the destemail.&lt;/span&gt;
action_mwl &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;bantime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(bantime)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(protocol)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
             %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-whois-lines[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(destemail)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;logpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;logpath&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ban &amp;amp; send a xarf e-mail to abuse contact of IP address and include relevant log lines&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to the destemail.&lt;/span&gt;
action_xarf &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;bantime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(bantime)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(protocol)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
             xarf-login-attack[service&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(sender)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;logpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;logpath&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ban IP on CloudFlare &amp;amp; send an e-mail with whois report and relevant log lines&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to the destemail.&lt;/span&gt;
action_cf_mwl &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; cloudflare[cfuser&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(cfemail)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;cftoken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(cfapikey)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
                %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-whois-lines[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(destemail)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;logpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;logpath&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Report block via blocklist.de fail2ban reporting service API&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See the IMPORTANT note in action.d/blocklist_de.conf for when to&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# use this action. Create a file jail.d/blocklist_de.local containing&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [Init]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# blocklist_de_apikey = {api key from registration]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
action_blocklist_de  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; blocklist_de[email&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(sender)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;apikey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(blocklist_de_apikey)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Report ban via badips.com, and use as blacklist&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See BadIPsAction docstring in config/action.d/badips.py for&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# documentation for this action.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# NOTE: This action relies on banaction being present on start and therefore&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# should be last action defined for a jail.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
action_badips &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; badips.py[category&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(name)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;banaction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(banaction)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Choose default action.  To change, just override value of 'action' with the&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# globally (section [DEFAULT]) or per specific section&lt;/span&gt;
action &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;action_&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# JAILS&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# SSH servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sshd]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ssh
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;sshd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sshd-ddos]
&lt;span class=&quot;c&quot;&gt;# This jail corresponds to the standard configuration in Fail2ban.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The mail-whois action send a notification e-mail with a whois request&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# in the body.&lt;/span&gt;
port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ssh
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;sshd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;dropbear]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ssh
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;dropbear_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;selinux-ssh]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ssh
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;auditd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# HTTP servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-auth]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-badbots]
&lt;span class=&quot;c&quot;&gt;# Ban hosts which agent identifies spammer robots crawling the web&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# for email addresses. The mail outputs are buffered.&lt;/span&gt;
port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_access_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 172800
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-noscript]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-overflows]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-nohome]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-botsearch]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-fakegooglebot]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_access_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1
ignorecommand &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ignorecommands_dir&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s/apache-fakegooglebot &amp;lt;ip&amp;gt;


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-modsecurity]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;apache-shellshock]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;nginx-http-auth]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;nginx_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;nginx-botsearch]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;nginx_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2

&lt;span class=&quot;c&quot;&gt;# Ban attackers that try to use PHP's URL-fopen() functionality&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# through GET/POST variables. - Experimental, with more than a year&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# of usage in production environments.&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;php-url-fopen]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;nginx_access_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
          %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_access_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;suhosin]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;suhosin_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;lighttpd-auth]
&lt;span class=&quot;c&quot;&gt;# Same as above for Apache's mod_auth&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# It catches wrong authentifications&lt;/span&gt;
port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;lighttpd_error_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Webmail and groupware servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;roundcube-auth]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;roundcube_errors_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;openwebmail]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/openwebmail.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;horde]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/horde/horde.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;groupoffice]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /home/groupoffice/log/info.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sogo-auth]
&lt;span class=&quot;c&quot;&gt;# Monitor SOGo groupware server&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# without proxy this would be:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# port    = 20000&lt;/span&gt;
port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/sogo/sogo.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;tine20]

logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/tine20/tine20.log
port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Web Applications&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;drupal-auth]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_daemon&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;guacamole]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/tomcat&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;/catalina.out

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;monit]
&lt;span class=&quot;c&quot;&gt;#Ban clients brute-forcing the monit gui login&lt;/span&gt;
filter   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; monit
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2812
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/monit


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;webmin-auth]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 10000
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_authpriv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;froxlor-auth]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_authpriv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# HTTP Proxy servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;squid]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  80,443,3128,8080
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/squid/access.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;3proxy]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 3128
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/3proxy.log


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# FTP servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;proftpd]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;proftpd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;pure-ftpd]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;pureftpd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;gssftpd]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_daemon&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;wuftpd]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;wuftpd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;vsftpd]
&lt;span class=&quot;c&quot;&gt;# or overwrite it in jails.local to be&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# logpath = %(syslog_authpriv)s&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# if you want to rely on PAM failed login attempts&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# vsftpd's failregex should match both of those formats&lt;/span&gt;
port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;vsftpd_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Mail servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ASSP SMTP Proxy Jail&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;assp]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /root/path/to/assp/logs/maillog.txt


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;courier-smtp]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;postfix]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;postfix_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;postfix-rbl]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sendmail-auth]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; submission,465,smtp
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sendmail-reject]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;qmail-rbl]

filter  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; qmail
port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /service/qmail/log/main/current


&lt;span class=&quot;c&quot;&gt;# dovecot defaults to logging to the mail syslog facility&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# but can be set by syslog_facility in the dovecot configuration.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;dovecot]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; pop3,pop3s,imap,imaps,submission,465,sieve
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;dovecot_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;sieve]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;dovecot_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;solid-pop3d]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; pop3,pop3s
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;solidpop3d_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;exim]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;exim_main_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;exim-spam]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;exim_main_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;kerio]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; imap,smtp,imaps,465
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /opt/kerio/mailserver/store/logs/security.log


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Mail servers authenticators: might be used for smtp,ftp,imap servers, so&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# all relevant ports get banned&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;courier-auth]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission,imap3,imaps,pop3,pop3s
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;postfix-sasl]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission,imap3,imaps,pop3,pop3s
&lt;span class=&quot;c&quot;&gt;# You might consider monitoring /var/log/mail.warn instead if you are&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# running postfix since it would provide the same log lines at the&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &quot;warn&quot; level but overall at the smaller filesize.&lt;/span&gt;
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;postfix_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;perdition]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; imap3,imaps,pop3,pop3s
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;squirrelmail]

port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; smtp,465,submission,imap2,imap3,imaps,pop3,pop3s,http,https,socks
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/lib/squirrelmail/prefs/squirrelmail_access_log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;cyrus-imap]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; imap3,imaps
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;uwimap-auth]

port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; imap3,imaps
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_mail&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# DNS servers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# !!! WARNING !!!&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   Since UDP is connection-less protocol, spoofing of IP and imitation&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   of illegal actions is way too simple.  Thus enabling of this filter&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   might provide an easy way for implementing a DoS against a chosen&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   victim. See&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   Please DO NOT USE this jail unless you know what you are doing.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# IMPORTANT: see filter.d/named-refused for instructions to enable logging&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This jail blocks UDP traffic for DNS requests.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [named-refused-udp]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# filter   = named-refused&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# port     = domain,953&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# protocol = udp&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# logpath  = /var/log/named/security.log&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# IMPORTANT: see filter.d/named-refused for instructions to enable logging&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This jail blocks TCP traffic for DNS requests.&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;named-refused]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; domain,953
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/named/security.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;nsd]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 53
action   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;udp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp]
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/nsd.log


&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Miscellaneous&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;asterisk]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5060,5061
action   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;udp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-whois[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(destemail)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/asterisk/messages
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 10


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;freeswitch]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5060,5061
action   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(port)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;udp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-whois[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s, &lt;span class=&quot;nv&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(destemail)s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/freeswitch.log
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 10


&lt;span class=&quot;c&quot;&gt;# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# equivalent section:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# log-warning = 2&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# for syslog (daemon facility)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [mysqld_safe]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# syslog&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# for own logfile&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# [mysqld]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# log-error=/var/log/mysqld.log&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;mysqld-auth]

port     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 3306
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;mysql_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5


&lt;span class=&quot;c&quot;&gt;# Jail for more extended banning of persistent abusers&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# !!! WARNINGS !!!&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 1. Make sure that your loglevel specified in fail2ban.conf/.local&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    is not at DEBUG level -- which might then cause fail2ban to fall into&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    an infinite loop constantly feeding itself with non-informative lines&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 2. Increase dbpurgeage defined in fail2ban.conf to e.g. 648000 (7.5 days)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    to maintain entries for failed logins for sufficient amount of time&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;recidive]

logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/fail2ban.log
banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-allports
bantime  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 604800  ; 1 week
findtime &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 86400   ; 1 day
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5


&lt;span class=&quot;c&quot;&gt;# Generic filter for PAM. Has to be used with action which bans all&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ports such as iptables-allports, shorewall&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;pam-generic]
&lt;span class=&quot;c&quot;&gt;# pam-generic filter can be customized to monitor specific subset of 'tty's&lt;/span&gt;
banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-allports
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_authpriv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;xinetd-fail]

banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-multiport-log
logpath   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_daemon&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
maxretry  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2


&lt;span class=&quot;c&quot;&gt;# stunnel - need to set port for this&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;stunnel]

logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/stunnel4/stunnel.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ejabberd-auth]

port    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 5222
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/ejabberd/ejabberd.log


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;counter-strike]

logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /opt/cstrike/logs/L[0-9]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.log
&lt;span class=&quot;c&quot;&gt;# Firewall: http://www.cstrike-planet.com/faq/6&lt;/span&gt;
tcpport &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
udpport &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
action  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(tcpport)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-tcp]
           %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s[name&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;__name__&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp, &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(udpport)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;udp&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;%(chain)s&quot;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;actname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;%&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;banaction&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s-udp]

&lt;span class=&quot;c&quot;&gt;# consider low maxretry and a long bantime&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# nobody except your own Nagios server should ever probe nrpe&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;nagios]

enabled  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;syslog_daemon&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s     ; nrpe.cfg may define a different log_facility
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1


&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;oracleims]
&lt;span class=&quot;c&quot;&gt;# see &quot;oracleims&quot; filter file for configuration requirement for Oracle IMS v6 and above&lt;/span&gt;
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /opt/sun/comms/messaging64/log/mail.log_current
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6
banaction &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; iptables-allports

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;directadmin]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/directadmin/login.log
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 2222

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;portsentry]
enabled  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/lib/portsentry/portsentry.history
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;pass2allow-ftp]
&lt;span class=&quot;c&quot;&gt;# this pass2allow example allows FTP traffic after successful HTTP authentication&lt;/span&gt;
port         &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; ftp,ftp-data,ftps,ftps-data
&lt;span class=&quot;c&quot;&gt;# knocking_url variable must be overridden to some secret value in filter.d/apache-pass.local&lt;/span&gt;
filter       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; apache-pass
&lt;span class=&quot;c&quot;&gt;# access log of the website with HTTP auth&lt;/span&gt;
logpath      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; %&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;apache_access_log&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;s
blocktype    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; RETURN
returntype   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; DROP
bantime      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 3600
maxretry     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1
findtime     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The above code is Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors
Copyright of modifications held by their respective authors.
Licensed under the GNU General Public License v2 (GPL).&lt;/p&gt;

&lt;p&gt;Written by Cyril Jaquier &lt;a href=&quot;mailto:cyril.jaquier@fail2ban.org&quot;&gt;cyril.jaquier@fail2ban.org&lt;/a&gt;.
Many contributions by Yaroslav O. Halchenko &lt;a href=&quot;mailto:debian@onerussian.com&quot;&gt;debian@onerussian.com&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/security/using-fail2ban-for-security&quot;&gt;Linode on Fail2ban for security&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.fail2ban.org/wiki&quot;&gt;Fail2ban wiki&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-fail2ban-works-to-protect-services-on-a-linux-server&quot;&gt;Digital Ocean on How Fail2ban protects a server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 17 Dec 2016 15:50:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/12/overriding-fail2ban-settings/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/12/overriding-fail2ban-settings/</guid>
      </item>
      
    
      
      <item>
        <title>Install LAMP Stack on Ubuntu 16.04 Xenial Xerus</title>
        <description>&lt;p&gt;Build notes for installing Apache, MariaDB, PHP.&lt;/p&gt;

&lt;h2 id=&quot;install-apache&quot;&gt;Install Apache&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install apache2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-php&quot;&gt;Install PHP&lt;/h2&gt;
&lt;p&gt;Install PHP with extra modules.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install php libapache2-mod-php php-mcrypt php-mysql&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-maria-db&quot;&gt;Install Maria DB&lt;/h2&gt;

&lt;p&gt;Use the online &lt;a href=&quot;https://downloads.mariadb.org/mariadb/repositories/#mirror=heanet-ltd&quot;&gt;respository configuration tool&lt;/a&gt;. Select a local mirror.&lt;/p&gt;

&lt;p&gt;Based on Ubuntu Xenial, stable release:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
sudo add-apt-repository &lt;span class=&quot;s1&quot;&gt;'deb [arch=amd64,i386,ppc64el] http://ftp.heanet.ie/mirrors/mariadb/repo/10.1/ubuntu xenial main'&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Once the key is imported, install MariaDB:&lt;/span&gt;
sudo apt-get update
sudo apt-get install mariadb-server&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Secure MariaDB by removing anonymous users, removing the test database and disallowing external access:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mysql_secure_installation&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-php-extras&quot;&gt;Install PHP Extras&lt;/h2&gt;
&lt;p&gt;For extensions available, enable with &lt;code class=&quot;highlighter-rouge&quot;&gt;phpenmod&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo phpenmod mcrypt
sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Extra extensions may be required. For example, if multibyte functions are used in apps, you will need &lt;code class=&quot;highlighter-rouge&quot;&gt;php-mbstring&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install php-mbstring
sudo phpenmod mbstring
sudo apt-get install php-xml
sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-phpmyadmin&quot;&gt;Install PHPMyAdmin&lt;/h2&gt;
&lt;p&gt;Install phpMyAdmin:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install phpmyadmin apache2-utils&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;An &lt;a href=&quot;https://en.wikipedia.org/wiki/Ncurses&quot;&gt;ncurses&lt;/a&gt; window will open that enables phpMyAdmin to be configured.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;To select a server, hit space then tab/return&lt;/li&gt;
  &lt;li&gt;Choose “yes” when asked “Configure database for phpmyadmin with dbconfig-common?”&lt;/li&gt;
  &lt;li&gt;Enter a password for phpMyAdmin when prompted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once installed, PHPMyAdmin needs to be added to the Apache config file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/apache2.conf

&lt;span class=&quot;c&quot;&gt;# Add the following line to the end of apache2.conf:&lt;/span&gt;

Include /etc/phpmyadmin/apache.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When installing phpMyAdmin on Xenial Xerus, you may encounter a blank white screen of death. Try checking the Apache error log to determine the problem:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tail -f /var/log/apache2/error.log
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In my case, the relevant error was:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[Fri Jun 17 20:04:50.205836 2016] [:error] [pid 8089] [client 127.0.0.1:34540] PHP Fatal error:  require_once(): Failed opening required '/usr/share/php/php-gettext/gettext.inc' (include_path='.:/usr/share/php') in /usr/share/phpmyadmin/libraries/select_lang.lib.php on line 477
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This means that the php-gettext extension is required. Install this and restart Apache to fix:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install php-gettext
sudo service apache2 restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sat, 17 Dec 2016 10:43:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/12/install-lamp-stack-on-ubuntu-xenial/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/12/install-lamp-stack-on-ubuntu-xenial/</guid>
      </item>
      
    
      
      <item>
        <title>Grunt Uncss and Jekyll</title>
        <description>&lt;p&gt;Front-end frameworks like &lt;a href=&quot;http://getbootstrap.com/&quot;&gt;Bootstrap&lt;/a&gt; and &lt;a href=&quot;http://foundation.zurb.com/&quot;&gt;Foundation&lt;/a&gt; provide a really good way to deliver high-quality modern responsive websites. They take care of the grunt work in terms of layout and common design elements and thereby drastically speed up development time.&lt;/p&gt;

&lt;p&gt;I don’t buy the argument that they constrain design. You can style and override these frameworks as required.&lt;/p&gt;

&lt;p&gt;They do have a major disadvantage -size. You’re often including (a lot of) rules in your stylesheet that are not used in the current project. Enter &lt;a href=&quot;https://github.com/giakki/uncss&quot;&gt;Uncss&lt;/a&gt;. This article describes how I use Uncss with &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; on &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; projects.&lt;/p&gt;

&lt;h2 id=&quot;uncss&quot;&gt;Uncss&lt;/h2&gt;
&lt;p&gt;Uncss is a node module that removes unused CSS from stylesheets.&lt;/p&gt;

&lt;p&gt;On a (fairly typical) recent Jekyll project, Uncss helped me to trim a &lt;strong&gt;190 kB&lt;/strong&gt; stylesheet down to &lt;strong&gt;32 kB&lt;/strong&gt;. This is great for user experience, as it speeds up page-load time. It’s probably better for the environment as well, as we’re zapping less bytes down the wire to get the same result.&lt;/p&gt;

&lt;p&gt;How Uncss works:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HTML files are loaded by &lt;a href=&quot;http://phantomjs.org/&quot;&gt;PhantomJS&lt;/a&gt;, a headless browser.&lt;/li&gt;
  &lt;li&gt;Stylesheets are parsed by &lt;a href=&quot;https://github.com/postcss/postcss&quot;&gt;PostCSS&lt;/a&gt; - a tool that allows JS plugins to transform styles.&lt;/li&gt;
  &lt;li&gt;If a selector is not found in the HTML files, it is removed.&lt;/li&gt;
  &lt;li&gt;Remaining rules are converted back to CSS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can specify rules to be ignired by Uncss - for example, styles that are added by JavaScript.&lt;/p&gt;

&lt;h2 id=&quot;grunt--uncss&quot;&gt;Grunt &amp;amp; Uncss&lt;/h2&gt;
&lt;p&gt;We use Grunt as a front end task runner on our Jekyll projects. No, I don’t care that it’s old-fashioned (!). It performs really well for us and there is no need to change it for a shinier tool in this context.&lt;/p&gt;

&lt;p&gt;We use the &lt;a href=&quot;https://github.com/addyosmani/grunt-uncss&quot;&gt;grunt-uncss&lt;/a&gt; grunt task to run Uncss in development.&lt;/p&gt;

&lt;p&gt;To install:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# npm&lt;/span&gt;
npm install grunt-uncss --save-dev

&lt;span class=&quot;c&quot;&gt;# better yet, use Yarn - it's quicker:&lt;/span&gt;
yarn add grunt-uncss --dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example-grunt-uncss-task&quot;&gt;Example grunt-uncss Task&lt;/h2&gt;
&lt;p&gt;We split out grunt tasks into separate files. Contents of a typical &lt;code class=&quot;highlighter-rouge&quot;&gt;config/uncss.js&lt;/code&gt; file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;dist&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;na&quot;&gt;options&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;na&quot;&gt;ignore&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;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\w\.&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;in/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.top-nav-collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'img-caption'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.top-nav-collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.fade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.collapsing'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;#|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.)&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;navbar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;(\-[&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;a-zA-Z&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)?&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;#|&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.)&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;dropdown&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;(\-[&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;a-zA-Z&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)?&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.slid.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.slide.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.fade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.fade.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.collapse.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.collapsing'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.alert-danger'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev.right'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.right'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'.navbar-fixed-top'&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;stylesheets&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;s1&quot;&gt;'../css/main.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;ignoreSheets&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;sr&quot;&gt;/fonts.googleapis/&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;na&quot;&gt;files&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;s1&quot;&gt;'css/main.un.css'&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;s1&quot;&gt;'_site/index.html'&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;grunt-uncss-with-jekyll&quot;&gt;Grunt Uncss with Jekyll&lt;/h2&gt;
&lt;p&gt;We manage all our Jekyll builds by means of Grunt tasks. Specifically, we use the &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-shell&lt;/code&gt; package to build and deploy Jekyll. This provides a convenient way of specifying different configurations for different environments.&lt;/p&gt;

&lt;p&gt;We generally include the uncss task on staging and production builds, but not on development builds. Actually we keep the staging build pretty much identical to production for better quality assurance.&lt;/p&gt;

&lt;p&gt;Before Grunt Uncss can work, it needs something to work &lt;em&gt;on&lt;/em&gt;, which is why the staging grunt task below starts with a Jekyll build (&lt;code class=&quot;highlighter-rouge&quot;&gt;'shell:jekyllNoMap'&lt;/code&gt;). More on the “NoMap” issue later…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Taken from `/Gruntfile.js`&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Deploy to Staging with `grunt deployStaging` then reset the local copy.&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'deployStaging'&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;s1&quot;&gt;'shell:jekyllNoMap'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// Build the site (to _site)&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'sass:production'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// Run sass task to build CSS&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'uncss:dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;// Run uncss on the built HTML/CSS&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'cssmin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;// Minify the processed CSS&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'uglify:dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// Uglify site JS&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'shell:jekyllStaging'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Run the staging build (CSS previously generated)&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'copy:fonts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;// Copy fonts to _site&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'shell:rsyncStaging'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Deploy to staging&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'sass:development'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// After deployment, run dev tasks (for convenience)&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'concat'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'shell:jekyllDev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'copy:fonts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'watch'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;problems-with-google-maps&quot;&gt;Problems with Google Maps&lt;/h2&gt;
&lt;p&gt;We recently experienced a problem with &lt;code class=&quot;highlighter-rouge&quot;&gt;gulp-uncss&lt;/code&gt; and Google maps. After updating the project, the Uncss task was providing an incomplete style sheet - with no error messages.&lt;/p&gt;

&lt;p&gt;Some ideas for debugging:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Look through the generated (un)css file and search for a style you know should be there: if it isn’t, uncss has encountered a problem&lt;/li&gt;
  &lt;li&gt;Make sure your HTML and CSS is valid&lt;/li&gt;
  &lt;li&gt;Comment out scripts and go through a process of elimination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this particular case, the problem was caused by a Google maps call in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;head&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://maps.googleapis.com/maps/api/js?key={{site.data.map.api-key}}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With this line commented out, uncss worked perfectly. I have a feeling that this issue is caused by PhantomJS and the fact that the site is running on the http protocol, whereas the link to Google is https.&lt;/p&gt;

&lt;p&gt;To be honest, sometimes you can’t justify the time to get to the bottom of issues like this - you just need a quick fix. Fortunately Jekyll makes it pretty easy to define environments by including multiple config files. For example, to build a dev environment you include a &lt;code class=&quot;highlighter-rouge&quot;&gt;_config_dev.yml&lt;/code&gt; config file in your Jekyll build. For example, see our &lt;code class=&quot;highlighter-rouge&quot;&gt;shell.js&lt;/code&gt; config:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;jekyllNoMap&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rm -rf _site/*; jekyll build --config _config.yml,_config_staging.yml,_config_no_map.yml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;jekyllStaging&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rm -rf _site/*; jekyll build --config _config.yml,_config_staging.yml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;jekyllDev&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rm -rf _site/*; jekyll build --config _config.yml,_config_dev.yml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;jekyllProduction&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rm -rf _site/*; jekyll build --config _config.yml,_config_production.yml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rsyncStaging&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'deploy-staging'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rsyncProduction&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'deploy-production'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The noMap config file &lt;code class=&quot;highlighter-rouge&quot;&gt;_config_no_map.yml&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;s&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://example.com/staging-site&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;baseurl&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/staging-site&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;production&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;staging&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;include-map&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can then exclude the map script if &lt;code class=&quot;highlighter-rouge&quot;&gt;include-map&lt;/code&gt; returns false:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- in &amp;lt;head&amp;gt; --&amp;gt;&lt;/span&gt;

{% if page.map-height != nil and site.include-map != false %}
    {% include partials/map-scripts.html %}
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 30 Nov 2016 10:34:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/11/grunt-uncss-and-jekyll/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/11/grunt-uncss-and-jekyll/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Reflection Error when Class Contains Errors</title>
        <description>&lt;p&gt;This is a quick note - intended to be a memory jogger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel will throw a ReflectionException error if a class contains an error.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;ReflectionException in Route.php line 339: Class App\Http\Requests\CreateLeadRequest does not exist&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is pretty logical - if the class can’t be instantiated, it doesn’t exist.&lt;/p&gt;

&lt;p&gt;It can be confusing if you’re looking at your project file tree and can see the class file (“I can see it - the class exists!”). In my case, I checked the calling class several times before bothering to check the content of the class that was being called - which was missing a comma.&lt;/p&gt;

&lt;p&gt;To prevent this kind of thing:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Use a PHP linter - &lt;a href=&quot;https://atom.io/packages/linter-php&quot;&gt;here’s one for Atom&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Check all the classes involved, especially the one you’re calling - don’t assume you’ve got an autoloading issue&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 15 Nov 2016 18:15:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/11/laravel-reflection-error-when-class-contains-errors/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/11/laravel-reflection-error-when-class-contains-errors/</guid>
      </item>
      
    
      
      <item>
        <title>Generate URLs to Named Routes in Laravel</title>
        <description>&lt;p&gt;Named routes in Laravel allow you to easily generate specific URLs. Referring to the named route throughout your project makes the codebase more robust. If a URL needs to be amended, this can be done easily by editing the route definition. Without named routes you’d need to amend all URL references to the amended route.&lt;/p&gt;

&lt;p&gt;Routes generated by the &lt;code class=&quot;highlighter-rouge&quot;&gt;Route::resource()&lt;/code&gt; method will automatically have named routes assigned - taking the format &lt;code class=&quot;highlighter-rouge&quot;&gt;resource.method&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;manually-specify-named-routes&quot;&gt;Manually Specify Named Routes&lt;/h2&gt;
&lt;p&gt;This is achieved by chaining the &lt;code class=&quot;highlighter-rouge&quot;&gt;name()&lt;/code&gt; method to the route definition:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Define route in `routes/web.php`
&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'about'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'pages.about'&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'about'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Or using a controller:
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'about'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'PageController@showAbout'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'about'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;generate-urls-to-named-routes&quot;&gt;Generate URLs to Named Routes&lt;/h2&gt;
&lt;p&gt;Laravel provides a global &lt;code class=&quot;highlighter-rouge&quot;&gt;route()&lt;/code&gt; function that gets the URL to a named route. The first Parameter is the route name (string). Depending on the route you’re trying to access you may also need to pass in an array of parameters as the second argument.&lt;/p&gt;

&lt;p&gt;Simple example, as it would look as an anchor tag within in a Blade template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ route('posts.show', [$id]) }}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Link to Resource {{ $id }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…this generates a URL that links to &lt;code class=&quot;highlighter-rouge&quot;&gt;posts/{id}&lt;/code&gt;. For example: &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/posts/10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;route()&lt;/code&gt; function accepts three parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Route name (string)&lt;/li&gt;
  &lt;li&gt;Parameters (mixed)&lt;/li&gt;
  &lt;li&gt;Absolute (boolean, true by default)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You could make the URL relative by passing in &lt;code class=&quot;highlighter-rouge&quot;&gt;false&lt;/code&gt; as a third argument to the function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ route('posts.show', [$id], false) }}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Link to Resource {{ $id }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…this generates: &lt;code class=&quot;highlighter-rouge&quot;&gt;/posts/10&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;adding-additional-parameters&quot;&gt;Adding Additional Parameters&lt;/h2&gt;
&lt;p&gt;The example above passes a single parameter (&lt;code class=&quot;highlighter-rouge&quot;&gt;$id&lt;/code&gt;) into the &lt;code class=&quot;highlighter-rouge&quot;&gt;route&lt;/code&gt; function. In this case, the ‘show’ method that is being hit expects a single argument - and this is correctly passed in. If more arguments are required (for example in the case of nested resources) they will be passed in the order specified in the &lt;code class=&quot;highlighter-rouge&quot;&gt;route()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Interestingly, Laravel is smart enough to know that additional parameters (beyond what is required by the accepting method) should be passed as GET parameters.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Define route in `routes/web.php`
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'posts/{post}/comments/{comment}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'CommentController@show'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'comment'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{-- Create link to named route in Blade --}
&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ route('comment', ['1', '2', 'par'=&amp;gt;'HELLO', 'par2'=&amp;gt;'Goodbye']) }}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;The Comment&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The generated URL looks like:
&lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/posts/1/comments/2?par=HELLO&amp;amp;par2=Goodbye&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This might be handy of you were redirecting back to a page - you could use the amended GET parameters to alter elements of the page display.&lt;/p&gt;

&lt;h2 id=&quot;using-within-laravel-collective-forms&quot;&gt;Using Within Laravel Collective Forms&lt;/h2&gt;
&lt;p&gt;If your project requires the &lt;a href=&quot;https://packagist.org/packages/laravelcollective/html&quot;&gt;Laravel Collective Forms &amp;amp; HTML package&lt;/a&gt;, you can use named routes to set the form by passing an array to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Form::open()&lt;/code&gt; method with with the key ‘route’:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{!! Form::open(['method' =&amp;gt; 'DELETE',
    'route' =&amp;gt; ['leads.destroy', $id],
    'id' =&amp;gt; 'form-delete-lead-' . $id])
    !!}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The ‘route’ array is comprised of ‘route.name’ followed by route parameters.&lt;/p&gt;

&lt;h2 id=&quot;redirects&quot;&gt;Redirects&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;Redirect::to()&lt;/code&gt; method will also accept a named route:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// redirect to http://example.com/leads?ship=Rocinante
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'leads.index'&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;s1&quot;&gt;'ship'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Rocinante'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 15 Nov 2016 10:13:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/11/generate-urls-to-named-routes-in-laravel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/11/generate-urls-to-named-routes-in-laravel/</guid>
      </item>
      
    
      
      <item>
        <title>Nested Resource Routes in Laravel</title>
        <description>&lt;p&gt;To create a resource controller, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;php artisan make:controller PostController --resource&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will create a controller with stubbed out methods for handling typical CRUD actions.&lt;/p&gt;

&lt;h2 id=&quot;resourceful-route-to-the-controller&quot;&gt;Resourceful Route to the Controller&lt;/h2&gt;
&lt;p&gt;The Laravel resourceful route goes hand-in-hand with the resource controller. To generate typical CRUD routes to the controller, add this line to &lt;code class=&quot;highlighter-rouge&quot;&gt;routes/web.php&lt;/code&gt; (Laravel 5.3+):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;Route::resource('posts', PostController);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This route declaration sets up multiple routes to the controller. You can view these routes by running &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan route:list&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;+--------+-----------+--------------------+---------------+---------------------------------------------+------------+
| Domain | Method    | URI                | Name          | Action                                      | Middleware |
+--------+-----------+--------------------+---------------+---------------------------------------------+------------+
|        | GET|HEAD  | /                  |               | Closure                                     | web        |
|        | GET|HEAD  | about              |               | Closure                                     | web        |
|        | GET|HEAD  | posts              | posts.index   | App\Http\Controllers\PostController@index   | web        |
|        | POST      | posts              | posts.store   | App\Http\Controllers\PostController@store   | web        |
|        | GET|HEAD  | posts/create       | posts.create  | App\Http\Controllers\PostController@create  | web        |
|        | GET|HEAD  | posts/{posts}      | posts.show    | App\Http\Controllers\PostController@show    | web        |
|        | PUT|PATCH | posts/{posts}      | posts.update  | App\Http\Controllers\PostController@update  | web        |
|        | DELETE    | posts/{posts}      | posts.destroy | App\Http\Controllers\PostController@destroy | web        |
|        | GET|HEAD  | posts/{posts}/edit | posts.edit    | App\Http\Controllers\PostController@edit    | web        |

+--------+-----------+--------------------+---------------+---------------------------------------------+------------+&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;nested-routes&quot;&gt;Nested Routes&lt;/h2&gt;
&lt;p&gt;Nested routes allow you to capture a relationship between resources within your routing. For example, resources from a &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt; model might be nested under a &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt; model: &lt;code class=&quot;highlighter-rouge&quot;&gt;users/{user}/posts/{post}&lt;/code&gt;. The resulting URL might look like this: &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/users/1/posts/10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To create nested routes, Laravel lets you use a dot notation. Sticking with the previous example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;Route::resource('users.posts', 'PostController');&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This would create a set of routes for posts that include the user identifier. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The ‘index’ route: &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/users/1/posts&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The ‘show’ route: &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/users/1/posts/10&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can override the out-of-the-box routes that are set up with the &lt;code class=&quot;highlighter-rouge&quot;&gt;resource()&lt;/code&gt; method, or add additional routes - you should add overrides &lt;em&gt;before&lt;/em&gt; the resource method.&lt;/p&gt;

&lt;p&gt;Nesting resources can make the URLs for your project unwieldy. They may also add complexity to your controllers - for example, the generated controller method stubs may require additional parameters, and you may need to pass additonal parameters when building forms.&lt;/p&gt;

&lt;h2 id=&quot;nested-resources-forms&quot;&gt;Nested Resources: Forms&lt;/h2&gt;
&lt;p&gt;When building a form action in the &lt;a href=&quot;https://laravelcollective.com/docs/5.3/html&quot;&gt;Laravel Collective Forms &amp;amp; HTML package&lt;/a&gt;, you need to pass in the additional parameters that are needed to build the route.&lt;/p&gt;

&lt;h3 id=&quot;create-new-resources&quot;&gt;Create New Resources&lt;/h3&gt;
&lt;p&gt;To set up a form action based on the route &lt;code class=&quot;highlighter-rouge&quot;&gt;users/{user}/post/{post}&lt;/code&gt; which is used to store a new resource:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{{-- Blade template ----------------------------------------------------------}}
{{-- Open the form and use a named route for submissions ---------------------}}
{!! Form::open(['route'=&amp;gt;['users.posts.store', $user_id]]) !!}
    {{-- Include the form to keep things DRY ---------------------------------}}
    @include('posts.form', ['submitButtonText' =&amp;gt; 'Create New Post'])
{!! Form::close() !!}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that only the user ID is required - this is a new post, so the post ID does not yet exist.&lt;/p&gt;

&lt;p&gt;The store method on &lt;code class=&quot;highlighter-rouge&quot;&gt;PostController&lt;/code&gt; might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Store a newly created Post in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$user_id&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;nv&quot;&gt;$user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findOrFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$user_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This relies on the user parameter being passed in through the URL. You could also not bother with this and do &lt;code class=&quot;highlighter-rouge&quot;&gt;Auth::user()-&amp;gt;posts()-&amp;gt;create($request-&amp;gt;all());&lt;/code&gt; to create the new post instead.&lt;/p&gt;

&lt;h3 id=&quot;edit-existing-resources&quot;&gt;Edit Existing Resources&lt;/h3&gt;
&lt;p&gt;To set the form action so that it spoofs a &lt;code class=&quot;highlighter-rouge&quot;&gt;PATCH&lt;/code&gt; method to the &lt;code class=&quot;highlighter-rouge&quot;&gt;users/{user}/posts/{post}/edit&lt;/code&gt; endpoint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{{-- Blade template ----------------------------------------------------------}}
{!! Form::model($post, ['method'=&amp;gt; 'PATCH', 'route'=&amp;gt;['users.posts.update', $user_id, $post-&amp;gt;id]]) !!}
    @include('posts.form', ['submitButtonText' =&amp;gt; 'Edit Post'])
{!! Form::close() !!}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To update the edited resource, you could use a controller update method like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Store a newly created Post in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $user_id
     * @param  int  $post_id
     * @return \Illuminate\Http\Response
     */&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Request&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$user_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_id&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;nv&quot;&gt;$post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findOrFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$post_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

         &lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'posts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the parameters you pass in need to be ordered as they are in the URL.&lt;/p&gt;

&lt;h2 id=&quot;checking-routes&quot;&gt;Checking Routes&lt;/h2&gt;
&lt;p&gt;If in doubt, check registered routes by running &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan route:list&lt;/code&gt; - which outputs a helpful table showing route names along with URLs and controller methods.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/controllers#restful-partial-resource-routes&quot;&gt;Laravel Docs on Controllers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 14 Nov 2016 17:44:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/11/nested-resource-routes-in-laravel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/11/nested-resource-routes-in-laravel/</guid>
      </item>
      
    
      
      <item>
        <title>Push to Named Stacks in Laravel Blade</title>
        <description>&lt;p&gt;Laravel blade usefully allows you to push to named stacks which can be rendered in different views. You can push either inline code, or a call to an external file.&lt;/p&gt;

&lt;h2 id=&quot;push-to-the-stack&quot;&gt;Push to the Stack&lt;/h2&gt;
&lt;p&gt;You can push to a given stack multiple times. Pushing is achieved by wrapping your code in &lt;code class=&quot;highlighter-rouge&quot;&gt;@push&lt;/code&gt;. This code triggers an alert confirmation if a delete form is submitted. The code is only required on one view, so pushing to the stack looks like a good option:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;@push('scripts-footer')
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&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;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.data-delete'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'click'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;resourceTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;confirm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Are you sure you want to delete '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;resourceTitle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'?'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#form-delete-'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'form'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;submit&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;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
@endpush&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This method can be quite nice for small bits of functionality as you can work on your script with the markup in front of you (you don’t have to remember data attributes etc). You could abstract your script out to an external file, and push a call to this file to the stack:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;@push('scripts-footer')
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/build/js/are-you-sure.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
@endpush&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;render-the-stack&quot;&gt;Render the Stack&lt;/h2&gt;
&lt;p&gt;Then in another template, output the stack. For example, in the blade template for the footer:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;@stack('scripts-footer')&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;more-stuff-to-explore&quot;&gt;More Stuff to Explore&lt;/h2&gt;
&lt;p&gt;Apparently if you &lt;code class=&quot;highlighter-rouge&quot;&gt;@push&lt;/code&gt; from inside a form using model binding, then you have access to that context. I haven’t tried this but it looks interesting.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/blade#stacks&quot;&gt;Laravel Blade Docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laracasts.com/discuss/channels/general-discussion/blade-push-and-stack-are-they-here-to-stay&quot;&gt;Laracasts Forum Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 19 Oct 2016 21:07:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/10/push-to-stacks-in-laravel-blade/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/10/push-to-stacks-in-laravel-blade/</guid>
      </item>
      
    
      
      <item>
        <title>Add Body Class on Laravel Views</title>
        <description>&lt;p&gt;It is useful to add resource-specific classes to the body class of a page to allow elements to be targeted by CSS.&lt;/p&gt;

&lt;h2 id=&quot;pass-variable-from-child-view-to-master-layout&quot;&gt;Pass Variable from Child View to Master Layout&lt;/h2&gt;
&lt;p&gt;Pass a relevant variable from the blade template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-blade&quot; data-lang=&quot;blade&quot;&gt;{{-- /views/articles/index.blade.php --}}
...
@extends('layouts.master', ['body_class' =&amp;gt; 'articles index'])
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then in &lt;code class=&quot;highlighter-rouge&quot;&gt;/views/layouts/master.blade.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-blade&quot; data-lang=&quot;blade&quot;&gt;&amp;lt;body
  @unless(empty($body_class))
    class=&quot;{{$body_class}}&quot;
  @endunless
  &amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You need to check that the variable is not empty - otherwise, if &lt;code class=&quot;highlighter-rouge&quot;&gt;$body_class&lt;/code&gt; isn’t passed in to the master template an error will occur.&lt;/p&gt;

&lt;h2 id=&quot;use-section&quot;&gt;Use @section&lt;/h2&gt;
&lt;p&gt;In the child blade template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-blade&quot; data-lang=&quot;blade&quot;&gt;@section('pageClass', 'js-home-page')&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the master:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-blade&quot; data-lang=&quot;blade&quot;&gt;&amp;lt;body class=&quot;@yield('pageClass')&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.reddit.com/r/laravel/comments/3i44nz/how_do_i_add_body_class_for_each_page/&quot;&gt;https://www.reddit.com/r/laravel/comments/3i44nz/how_do_i_add_body_class_for_each_page/&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 15 Oct 2016 19:13:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/10/add-body-class-on-laravel-views/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/10/add-body-class-on-laravel-views/</guid>
      </item>
      
    
      
      <item>
        <title>Grep Commands Cheatsheet</title>
        <description>&lt;p&gt;Grep is a handy command-line utility that enables you to search text or files.&lt;/p&gt;

&lt;p&gt;More formally: Grep (Global Regular Expression Print) is a utility for searching plain-text datasets for lines that match a given regular expression.&lt;/p&gt;

&lt;p&gt;Grep was developed for Unix, but is now available for all unix-like systems (e.g. Linux).&lt;/p&gt;

&lt;h2 id=&quot;basic-command-syntax&quot;&gt;Basic Command Syntax&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Output all lines that contain 'target string' in filename.log&lt;/span&gt;
grep &lt;span class=&quot;s1&quot;&gt;'target string'&lt;/span&gt; /var/log/filename.log

&lt;span class=&quot;c&quot;&gt;# Output all lines that contain 'target string' in multiple files&lt;/span&gt;
grep &lt;span class=&quot;s1&quot;&gt;'target string'&lt;/span&gt; filename1 filename2 filename3&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;ignore-case&quot;&gt;Ignore Case&lt;/h2&gt;
&lt;p&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Return lines containing 'David', 'david', 'DAVID' etc&lt;/span&gt;
grep -i &lt;span class=&quot;s1&quot;&gt;'david'&lt;/span&gt; /var/log/auth.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;recursive-search&quot;&gt;Recursive Search&lt;/h2&gt;
&lt;p&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;-r&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Search all apache log files for example.com/about&lt;/span&gt;
grep -r &lt;span class=&quot;s2&quot;&gt;&quot;example.com/about&quot;&lt;/span&gt; /var/log/apache2

&lt;span class=&quot;c&quot;&gt;# Sample Output:&lt;/span&gt;
/var/log/apache2/example.com.access.log.1:88.87.168.109 - - &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;12/Oct/2016:21:33:16 +0100] &lt;span class=&quot;s2&quot;&gt;&quot;GET /uploads/2015/08/example.jpg HTTP/1.1&quot;&lt;/span&gt; 200 628726 &lt;span class=&quot;s2&quot;&gt;&quot;http://example.com/about/&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Mozilla/5.0 (Linux; Android 6.0.1; SM-G920F Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.124 Mobile Safari/537.36&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To suppress the filename. use the &lt;code class=&quot;highlighter-rouge&quot;&gt;-h&lt;/code&gt; option. This example shows suppressed filenames and sends the result output to a file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grep -h -r &lt;span class=&quot;s2&quot;&gt;&quot;example.com/about&quot;&lt;/span&gt; /var/log/apache2 &amp;gt; ~/about-log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;search-for-whole-words&quot;&gt;Search for Whole Words&lt;/h2&gt;
&lt;p&gt;Grep will return lines that contain the target string - it may be a fragment of another string. To return only lines containing the target string as a distinct word, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;-w&lt;/code&gt; option:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Return lines containing 'example' as a distinct word&lt;/span&gt;
grep -w &lt;span class=&quot;s1&quot;&gt;'example'&lt;/span&gt; /var/log/logfile.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Search for many words requires &lt;code class=&quot;highlighter-rouge&quot;&gt;egrep&lt;/code&gt; (extended grep), or escaping the pipe character:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Returns lines that contain either specified word using egrep&lt;/span&gt;
egrep -w &lt;span class=&quot;s2&quot;&gt;&quot;david|elaine&quot;&lt;/span&gt; /var/log/auth.log

&lt;span class=&quot;c&quot;&gt;# Same:&lt;/span&gt;
grep -w &lt;span class=&quot;s2&quot;&gt;&quot;david&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;elaine&quot;&lt;/span&gt; /var/log/auth.log

&lt;span class=&quot;c&quot;&gt;# Recursively search apache logs for either specified string:&lt;/span&gt;
egrep -Rwi --color &lt;span class=&quot;s1&quot;&gt;'example.com/about|example.com/contact'&lt;/span&gt; /var/log/apache2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Grep&quot;&gt;Grep Definition&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cyberciti.biz/faq/searching-multiple-words-string-using-grep/&quot;&gt;http://www.cyberciti.biz/faq/searching-multiple-words-string-using-grep/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.howtoforge.com/tutorial/linux-grep-command/&quot;&gt;https://www.howtoforge.com/tutorial/linux-grep-command/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 13 Oct 2016 10:56:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/10/grep-commands-cheatsheet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/10/grep-commands-cheatsheet/</guid>
      </item>
      
    
      
      <item>
        <title>Variable Variables in PHP</title>
        <description>&lt;p&gt;PHP allows you to set dynamic variable names. This can be very useful when working with arrays and loops.&lt;/p&gt;

&lt;p&gt;To use a variable in a variable declaration, wrap the declaration in curly brackets.&lt;/p&gt;

&lt;p&gt;This is an example of a variable variable being used to build a form element in the context of a WordPress widget:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'mobile'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'landline'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$option&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;nv&quot;&gt;$fieldname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_text'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;
    Set the text for &lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$fieldname&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_text'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this example, during each loop the “value” attribute is set to a variable which is built on the fly. During the first iteration, the value attribute looks like &lt;code class=&quot;highlighter-rouge&quot;&gt;value=&quot;&amp;lt;?= $mobile_text; ?&amp;gt;&quot;&lt;/code&gt;. This variable allows us to retrieve previously saved data that is represented by &lt;code class=&quot;highlighter-rouge&quot;&gt;$mobile_text&lt;/code&gt;. On the next loop, the value will be set to &lt;code class=&quot;highlighter-rouge&quot;&gt;$landline_text&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.dummies.com/programming/php/how-to-use-php-variable-variables/&quot;&gt;Variable variables for dummies&lt;/a&gt;
&lt;a href=&quot;http://php.net/manual/en/language.variables.variable.php&quot;&gt;PHP man page&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 07 Oct 2016 18:36:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/10/variable-variables-in-php/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/10/variable-variables-in-php/</guid>
      </item>
      
    
      
      <item>
        <title>Install Ruby &amp; Ruby on Rails in Ubuntu Xenial</title>
        <description>&lt;p&gt;This guide involves:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Setting up Ruby using rbenv&lt;/li&gt;
  &lt;li&gt;Installing Node&lt;/li&gt;
  &lt;li&gt;Installing Rails&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install-ruby-dependencies&quot;&gt;Install Ruby Dependencies&lt;/h2&gt;

&lt;p&gt;Packages required to build ruby.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-rbenv--ruby-build&quot;&gt;Install rbenv &amp;amp; ruby-build&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone https://github.com/rbenv/rbenv.git ~/.rbenv
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'export PATH=&quot;$HOME/.rbenv/bin:$PATH&quot;'&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc

&lt;span class=&quot;c&quot;&gt;# Add command completion scripts into path&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'eval &quot;$(rbenv init -)&quot;'&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SHELL&lt;/span&gt;

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'export PATH=&quot;$HOME/.rbenv/plugins/ruby-build/bin:$PATH&quot;'&lt;/span&gt; &amp;gt;&amp;gt; ~/.bashrc
&lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SHELL&lt;/span&gt;

rbenv install 2.3.1
rbenv global 2.3.1
ruby -v&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;install-bundler&quot;&gt;Install Bundler&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gem install bundler
rbenv rehash&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-git-globally&quot;&gt;Set Up Git Globally&lt;/h2&gt;
&lt;p&gt;If you haven’t already done it…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git config --global color.ui &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;git config --global user.name &lt;span class=&quot;s2&quot;&gt;&quot;David Egan&quot;&lt;/span&gt;
git config --global user.email &lt;span class=&quot;s2&quot;&gt;&quot;you@example.com&quot;&lt;/span&gt;
ssh-keygen -t rsa -b 4096 -C &lt;span class=&quot;s2&quot;&gt;&quot;you@example.com on xenial-ghost&quot;&lt;/span&gt;
cat ~/.ssh/id_rsa.pub&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Copy and paste the contents of the public key to Github/BitBucket.&lt;/p&gt;

&lt;p&gt;Check the ssh connection:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh -T git@github.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-node&quot;&gt;Set Up Node&lt;/h2&gt;
&lt;p&gt;Install Node using NVM (Node Version Manager)&lt;/p&gt;

&lt;p&gt;See: http://linoxide.com/ubuntu-how-to/installing-nodejs-ubuntu-16-04/&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
sudo apt-get install build-essential libssl-dev curl
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.profile
nvm ls-remote
nvm install v6.2.2
node -v&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Build a quick hello world node app to check:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nano hello.js

# Enter:
a=&quot;Nice&quot;;
b=&quot;One!&quot;
c=2;
d=2;
e=c+d;
console.log(c +' plus '+d+' equals:' +e);
console.log('Hello World! '+a+' '+b);
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;node hello.js&lt;/code&gt; in the terminal to output:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2 plus 2 equals:4
Hello World! Nice One!
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;install-rails&quot;&gt;Install Rails&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gem install rails -v 4.2.6
rbenv rehash
rails -v&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;build-a-new-rails-app-using-mysqlmariadb&quot;&gt;Build a New Rails App using MySQL(MariaDB)&lt;/h2&gt;

&lt;p&gt;Assuming that a MySQL server is already installed on the system, prepare Rails for MySQL:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Requirement to compile the mysql2 gem
sudo apt-get install libmysqlclient-dev

# Gem used by Rails to connect to MySQL
gem install mysql2
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Set up new Rails app:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rails new railsapp -d mysql
cd railsapp
rake db:create
rails server
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://gorails.com/setup/ubuntu/16.04&quot;&gt;https://gorails.com/setup/ubuntu/16.04&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://linoxide.com/ubuntu-how-to/installing-nodejs-ubuntu-16-04/&quot;&gt;Install Node on Ubuntu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.inversoft.com/guides/2016-guide-to-user-data-security&quot;&gt;Server Security Guide, Inversoft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 02 Oct 2016 11:53:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/10/install-ruby-ruby-on-rails-in-ubuntu-xenial/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/10/install-ruby-ruby-on-rails-in-ubuntu-xenial/</guid>
      </item>
      
    
      
      <item>
        <title>Preventing User Enumeration in WordPress</title>
        <description>&lt;p&gt;We recently had to deal with a hacking attempt against a client WordPress site that had a few interesting aspects. The fix involved additional &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; rules to block user enumeration.&lt;/p&gt;

&lt;p&gt;We experienced multiple failed login attempts against WordPress. This wasn’t particularly worrying - the originating IP address was automatically blocked by our Fail2Ban setup after three unsuccessful attempts. The attacker (probably a script) then switched IP address and repeated the process, trigerring a further ban and repeating the cycle. The attack lasted for approximately 10 minutes and triggered more than 50 bans.&lt;/p&gt;

&lt;p&gt;The attack focused on usernames that were very close to (but not actually the same as) actual usernames on the site. It looked like a partially-successful user-enumeration attempt made up the initial phase of the attack. Puzzlingly, only some usernames had been enumerated.&lt;/p&gt;

&lt;h2 id=&quot;user-enumeration&quot;&gt;User Enumeration&lt;/h2&gt;
&lt;p&gt;User Enumeration is when would-be attackers collect usernames by interacting with your app. Unfortunately, by default WordPress makes this process easy. Entering &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/?author=1&lt;/code&gt; in the browser will trigger display of all articles authored by the user with an ID of ‘1’ - along with their registered username. This provides would-be attackers with a toe-hold - they can attempt to log in to valid usernames rather than having to guess.&lt;/p&gt;

&lt;p&gt;Our usual setup involves user-enumeration prevention measures - so it was surprising to see (almost valid) usernames cropping up in the log.&lt;/p&gt;

&lt;p&gt;It turns out that our user-enumeration prevention relied on ‘redirect_canonical’ WordPress filter. This filter is triggered if you navigate to &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/?author=1&lt;/code&gt; - in this case, it performs a redirect to the Author archives for the author with an ID of 1.&lt;/p&gt;

&lt;p class=&quot;emphasis-block&quot;&gt;The problem: If a registered user on the site has not authored any articles, the redirect will not take place. The user does not have an archive, the redirect doesn’t take place, and the user-enumeration can proceed.&lt;/p&gt;

&lt;p&gt;In our case, the enumerated users had a custom membership role rather than an author role - so they will never have an archive page. In our context, these are pretty low risk users, with very few permissions on the site. Nevertheless, it’s a pain having to check when these attacks occur, and it places unecessary load on the server.&lt;/p&gt;

&lt;p&gt;We verified the partially successful enumeration attempt by doing some penetration testing using &lt;a href=&quot;https://github.com/wpscanteam/wpscan&quot;&gt;WPScan&lt;/a&gt; - this turned up the exact “usernames” that were tried during the hack attempt.&lt;/p&gt;

&lt;p&gt;The solution involved extra &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; rules to prevent user-enumeration. We also added some extra rules to block login attempts using the enumerated (incorrect) usernames - just in case the attacker is logging them for future usage.&lt;/p&gt;

&lt;h2 id=&quot;htaccess-rule-to-prevent-user-enumeration&quot;&gt;.htaccess Rule to Prevent User enumeration&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt;	On
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt;	%{REQUEST_URI}	!^/wp-admin [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt;	%{QUERY_STRING}	author=\d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt;	(.*)		$1? [L,R=301]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;/h2&gt;
&lt;h3 id=&quot;line-one&quot;&gt;Line One&lt;/h3&gt;
&lt;p&gt;Turn on rewriting functionality - the Apache &lt;code class=&quot;highlighter-rouge&quot;&gt;mod_rewrite&lt;/code&gt; module must be installed on the server. This module rewrites requested URLs on the fly by means of a rule-based rewriting engine. The rewrite engine is based on a &lt;a href=&quot;http://www.pcre.org/&quot;&gt;Perl Compatible Regular Expressions(PCRE)&lt;/a&gt; parser.&lt;/p&gt;

&lt;h3 id=&quot;line-2&quot;&gt;Line 2&lt;/h3&gt;
&lt;p&gt;Apply a rewrite condition such that the rule will be ignored if the &lt;code class=&quot;highlighter-rouge&quot;&gt;REQUEST_URI&lt;/code&gt; begins with &lt;code class=&quot;highlighter-rouge&quot;&gt;/wp-admin&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;REQUEST_URI&lt;/p&gt;

  &lt;p&gt;The path component of the requested URI, such as “/index.html”. This notably excludes the query string which is available as its own variable named QUERY_STRING.
— &lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_rewrite.html#page-header&quot;&gt;Apache mod_rewrite Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;REQUEST_URI&lt;/code&gt; in simple terms is the bit after your domain.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;author=\d&lt;/code&gt; string that we’ll use to match the user enumeration attempt is used legitimately to display author posts in back end - so the rewrite rule should not apply if the request takes place in the WordPress admin area.&lt;/p&gt;

&lt;h3 id=&quot;line-3&quot;&gt;Line 3&lt;/h3&gt;
&lt;p&gt;Specify the rewrite condition - the target query string must include &lt;code class=&quot;highlighter-rouge&quot;&gt;'author=\d'&lt;/code&gt;, where &lt;code class=&quot;highlighter-rouge&quot;&gt;\d&lt;/code&gt; means a single digit.&lt;/p&gt;

&lt;p&gt;This means that &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/?dummy&amp;amp;author=1&lt;/code&gt; will trigger the rewrite, as will &lt;code class=&quot;highlighter-rouge&quot;&gt;http://example.com/?dummy&amp;amp;author=100&lt;/code&gt; - provided we’re not in the admin area, as specified by the previous condition.&lt;/p&gt;

&lt;p&gt;Note that the rule doesn’t specify that the ‘author’ variable is at the start of the query string (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;^/?author=([0-9]*)&lt;/code&gt; - a query string that starts with &lt;code class=&quot;highlighter-rouge&quot;&gt;/?author=&lt;/code&gt; followed by any number of digits).&lt;/p&gt;

&lt;h3 id=&quot;line-4&quot;&gt;Line 4&lt;/h3&gt;
&lt;p&gt;The rewrite rule: replace the entire path &lt;code class=&quot;highlighter-rouge&quot;&gt;(.*)&lt;/code&gt; with itself &lt;code class=&quot;highlighter-rouge&quot;&gt;$1&lt;/code&gt; but with an empty query string &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Make this the last rule and specify that it is a permanent redirect &lt;code class=&quot;highlighter-rouge&quot;&gt;[L,R=301]&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tldr-htaccess-rules&quot;&gt;TLDR: .htaccess Rules&lt;/h2&gt;
&lt;p&gt;Add these rules to .htaccess to prevent all malicious user-enumeration attempts. Such attempts will redirect to the site home page:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt;	On
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt;	%{REQUEST_URI}	!^/wp-admin [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt;	%{QUERY_STRING}	author=\d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt;	(.*)		$1? [L,R=301]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that preventing user-enumeration is only one component of an effective security policy.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_rewrite.html&quot;&gt;Apache mod_rewrite&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/3457460/3590673&quot;&gt;http://stackoverflow.com/a/3457460/3590673&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wordpress.stackexchange.com/a/130171/67129&quot;&gt;http://wordpress.stackexchange.com/a/130171/67129&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 30 Sep 2016 15:54:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/preventing-user-enumeration-in-wordpress/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/preventing-user-enumeration-in-wordpress/</guid>
      </item>
      
    
      
      <item>
        <title>Inject Menu Item into a Specific WordPress Menu</title>
        <description>&lt;p&gt;The ‘wp_nav_menu_items’ WordPress filter allows you to filter the HTML list content for nav menus.&lt;/p&gt;

&lt;p&gt;The filter can accept up to two parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The HTML list content (&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;li&amp;gt;&lt;/code&gt;s)&lt;/li&gt;
  &lt;li&gt;An object containing &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_nav_menu()&lt;/code&gt; arguments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Passing in the second parameter allows you to target the nav menu. The following code appends a new menu item to the ‘Primary Navigation’ menu:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'wp_nav_menu_items'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu_object&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;

  &lt;span class=&quot;nv&quot;&gt;$menu_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu_object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;menu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Only append the new li to the 'Primary Navigation' menu.
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Change 'Primary Navigation' for the name of the menu that you'd like to amend.
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Primary Navigation'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu_name&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;nv&quot;&gt;$new_li&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;li&amp;gt;&amp;lt;a class='btn btn-default' href='#'&amp;gt;The New Link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$new_li&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;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.wordpress.org/reference/hooks/wp_nav_menu_items/&quot;&gt;‘wp_nav_menu_items’ documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 28 Sep 2016 16:30:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/inject-menu-item-into-a-specific-wordpress-menu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/inject-menu-item-into-a-specific-wordpress-menu/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Basic Ajax</title>
        <description>&lt;p&gt;The WordPress way of handling AJAX requests is to use a specially constructed hook name built from the ‘action’ property of your AJAX request prepended with ‘wp_ajax_’ or ‘wp_ajax_nopriv_’.&lt;/p&gt;

&lt;p&gt;In a namespaced setup (like Roots\Sage) you’d set up hooks and callbacks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'wp_ajax_my_custom_action'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__NAMESPACE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\\ajax_processor'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'wp_ajax_nopriv_my_custom_action'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__NAMESPACE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\\ajax_processor'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ajax_processor&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;c1&quot;&gt;// Validate incoming POST data before further processing - return errors if necessary
&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$currency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'currency'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Do stuff, return true on success
&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$processed_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data_processor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$currency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$processed_data&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;c1&quot;&gt;// Success condition: send back stuff to alter in the browser
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'status'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'success!!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'postedData'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'currencySelected'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$currency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'price'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$price&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Error condition: Build an informative error message
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'error'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'foo'&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;c1&quot;&gt;// send $response back as a JSON object
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_send_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, when you send an AJAX request to WordPress with a request ‘action’ property set to ‘my_custom_action’ the hook callback will be automatically executed.&lt;/p&gt;

&lt;p&gt;If you’re using the ‘nopriv’ option (for users who are not logged in) your ajaxurl property won’t be automatically defined, so you need to include it manually or pass it in via &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_localize_script()&lt;/code&gt; within the enqueuing script. You should enqueue the javascript in any case.&lt;/p&gt;

&lt;h2 id=&quot;enqueue-javascript&quot;&gt;Enqueue JavaScript&lt;/h2&gt;
&lt;p&gt;In the context of Sage, create a JavaScript file in /assets/js. You then need to specify that this file should be built in with your front end processor. In Sage, you do this by providing the relevant info in &lt;code class=&quot;highlighter-rouge&quot;&gt;manifest.json&lt;/code&gt;. This instructs Gulp (Sage 8.x) to process your JS file and build it into the &lt;code class=&quot;highlighter-rouge&quot;&gt;dist&lt;/code&gt; directory - where it can be accessed.&lt;/p&gt;

&lt;p&gt;Simplified manifest.json, adding &lt;code class=&quot;highlighter-rouge&quot;&gt;test.js&lt;/code&gt; to our build directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;dependencies&quot;&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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main.js&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;files&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;scripts/main.js&quot;&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;nt&quot;&gt;&quot;main&quot;&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;kc&quot;&gt;true&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;nt&quot;&gt;&quot;test.js&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;files&quot;&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;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;scripts/test.js&quot;&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;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main.css&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;files&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;styles/main.scss&quot;&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;nt&quot;&gt;&quot;main&quot;&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;kc&quot;&gt;true&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;nt&quot;&gt;&quot;config&quot;&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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;devUrl&quot;&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;s2&quot;&gt;&quot;http://localhost/sage-test&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next up, enqueue the script. Sage provides a useful helper function to access the file path: &lt;code class=&quot;highlighter-rouge&quot;&gt;Roots\Sage\Assets\asset_path()&lt;/code&gt;. Depending on the location of your enqueuing script, you may need to import the namespace.&lt;/p&gt;

&lt;p&gt;Enqueuing from &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/extras.php&lt;/code&gt; might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Roots\Sage\Assets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'wp_enqueue_scripts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&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;nx&quot;&gt;wp_register_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'your_custom_handle'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Assets\asset_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'scripts/test.js'&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;s1&quot;&gt;'jquery'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;wp_enqueue_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'your_custom_handle'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;wp_localize_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'your_custom_handle'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'yourVars'&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;s1&quot;&gt;'yourAjaxURL'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;admin_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'admin-ajax.php'&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;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;the-javascript&quot;&gt;The JavaScript&lt;/h2&gt;
&lt;p&gt;A simple jQuery AJAX handler might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;yourVars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;yourAjaxURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#currency'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;change&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'action'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'my_custom_action'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'currency'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#currency'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;val&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;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;response&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Currency Selected: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currencySelected&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;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is designed to take and submit data from an on-page form that might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;post&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;currencyselector&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;currencyselector&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;select&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;currency&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;currency&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value =&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;USD&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;USD&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value =&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;GBP&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;GBP&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value =&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;EUR&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;EUR&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This example is just a stripped down version - mainly it’s a memory jogger for the hook name setup. I would generally build this functionality in an Object Oriented context - so the callbacks would be held within class methods rather than the functions shown here.&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Sep 2016 11:50:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/wordpress-basic-ajax/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/wordpress-basic-ajax/</guid>
      </item>
      
    
      
      <item>
        <title>Embed Google Slides in Jekyll</title>
        <description>&lt;p&gt;To embed a Google Slides presentation in a Jekyll post or page, open the presentation and select “Publish to Web” from the “File” menu.&lt;/p&gt;

&lt;p&gt;Choose the options you require, then select the “Embed” tab. You’ll be provided with an embed code for an iframe, that you simply paste into your Jekyll post or page. Generate your site as usual, and the iframe with your presentation will be embedded. When Jekyll parses markdown files, it will render any HTML that it finds.&lt;/p&gt;

&lt;p&gt;It won’t be responsive out of the box, so you’ll need a bit of CSS. I’ve shown this inline, but you could add the CSS to your stylesheet.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.responsive-wrap&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;iframe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;responsive-wrap&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- this is the embed code provided by Google --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://docs.google.com/presentation/d/1F0DQTNPg3YG_By6LMGcgwT3icJ3eMhCiupAZm76CIfE/embed?start=false&amp;amp;loop=false&amp;amp;delayms=3000&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;frameborder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;960&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;569&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;allowfullscreen=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;mozallowfullscreen=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;webkitallowfullscreen=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Google embed ends --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;working-example&quot;&gt;Working Example&lt;/h2&gt;
&lt;style&gt;
.responsive-wrap iframe{ max-width: 100%;}
&lt;/style&gt;

&lt;div class=&quot;responsive-wrap&quot;&gt;
  &lt;iframe src=&quot;https://docs.google.com/presentation/d/1F0DQTNPg3YG_By6LMGcgwT3icJ3eMhCiupAZm76CIfE/embed?start=false&amp;amp;loop=false&amp;amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;960&quot; height=&quot;569&quot; allowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 26 Sep 2016 11:23:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/embed-google-slides-in-jekyll/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/embed-google-slides-in-jekyll/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Front End Assets Quickstart</title>
        <description>&lt;p&gt;Laravel is pre-configured to use Node and Gulp (wrapped in Laravel &lt;code class=&quot;highlighter-rouge&quot;&gt;elixir&lt;/code&gt;) to manage and build front-end assets.&lt;/p&gt;

&lt;p&gt;Node is used to manage dependencies.&lt;/p&gt;

&lt;h2 id=&quot;quick-start-bootstrap&quot;&gt;Quick Start Bootstrap&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;In the project root run &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install&lt;/code&gt; to fetch the packages defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Enter &lt;code class=&quot;highlighter-rouge&quot;&gt;gulp&lt;/code&gt; to run the default elixir task&lt;/li&gt;
  &lt;li&gt;Bootstrap SASS files will be built in to &lt;code class=&quot;highlighter-rouge&quot;&gt;resources/assets/sass/app.scss&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;There is a font &lt;code class=&quot;highlighter-rouge&quot;&gt;@import&lt;/code&gt; rule in &lt;code class=&quot;highlighter-rouge&quot;&gt;resources/assets/sass/app.scss&lt;/code&gt; - more efficient to import fonts via HTML&lt;/li&gt;
  &lt;li&gt;Starter variables file at &lt;code class=&quot;highlighter-rouge&quot;&gt;resources/assets/sass/variables.scss&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;set-node-version&quot;&gt;Set Node Version&lt;/h2&gt;
&lt;p&gt;A modern node is required - if necessary use &lt;code class=&quot;highlighter-rouge&quot;&gt;nvm&lt;/code&gt; to load in a suitable version:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;nvm ls &lt;span class=&quot;c&quot;&gt;# List available local node versions&lt;/span&gt;
nvm ls-remote &lt;span class=&quot;c&quot;&gt;# List available remote node versions&lt;/span&gt;
nvm install v6.5.0 &lt;span class=&quot;c&quot;&gt;# Install v6.5.0&lt;/span&gt;
nvm use v6.5.0 &lt;span class=&quot;c&quot;&gt;# Use v6.5.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See &lt;a href=&quot;https://github.com/creationix/nvm&quot;&gt;nvm&lt;/a&gt; for more.&lt;/p&gt;

&lt;h2 id=&quot;versioning&quot;&gt;Versioning&lt;/h2&gt;
&lt;p&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;Gulpfile.js&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elixir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'laravel-elixir'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'laravel-elixir-vue-2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for your application as well as publishing vendor resources.
 |
 */&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;elixir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'app.scss'&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;nx&quot;&gt;webpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'app.js'&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;nx&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'css/app.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'js/app.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// app.css and app.js are now cache-busting;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Add glyphicons from Bootstrap&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'node_modules/bootstrap-sass/assets/fonts/bootstrap/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'public/build/fonts/bootstrap'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;browserify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'app.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Reference the versioned CSS file in a blade view - possibly &lt;code class=&quot;highlighter-rouge&quot;&gt;resources/views/partials/head.blade.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ elixir ('css/app.css') }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;media=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;screen&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;no title&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Reference the versioned JavaScript file in a blade view - possibly &lt;code class=&quot;highlighter-rouge&quot;&gt;resources/views/partials/footer.blade.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ elixir ('js/app.js') }}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
@stack('script-footer')&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 22 Sep 2016 20:41:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/laravel-front-end-assets-quickstart/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/laravel-front-end-assets-quickstart/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Form Validation Primer</title>
        <description>&lt;p&gt;Form validation logic can be held in an extension of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Request&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;The Request class allows your script to get an instance of the current HTTP request.  This is achieved by type hinting the Request class on the controller method. Dependency injection of The HTTP request then happens automatically.&lt;/p&gt;

&lt;p&gt;Fortunately, Laravel has a built-in Artisan command that facilitates the generation of custom requests.&lt;/p&gt;

&lt;h2 id=&quot;create-a-custom-request&quot;&gt;Create a Custom Request&lt;/h2&gt;
&lt;p&gt;Create a new form request class using Artisan:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:request ArticleRequest&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This stubs out a form request class under &lt;code class=&quot;highlighter-rouge&quot;&gt;/app/Http/Requests&lt;/code&gt; - in this case the new file is: &lt;code class=&quot;highlighter-rouge&quot;&gt;app/Http/Requests/ArticleRequest.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The file contains a new &lt;code class=&quot;highlighter-rouge&quot;&gt;ArticleRequest&lt;/code&gt; class, which extends &lt;code class=&quot;highlighter-rouge&quot;&gt;FormRequest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;FormRequest&lt;/code&gt; in turn extends the basic Laravel &lt;code class=&quot;highlighter-rouge&quot;&gt;Request&lt;/code&gt; class - which in turn extends the Symfony &lt;code class=&quot;highlighter-rouge&quot;&gt;Request&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;It’s probably better to keep the class name a bit general - &lt;code class=&quot;highlighter-rouge&quot;&gt;ArticleRequest&lt;/code&gt; is probably better than &lt;code class=&quot;highlighter-rouge&quot;&gt;CreateArticleRequest&lt;/code&gt; - as the same validation logic can be used for forms used to create &lt;strong&gt;and&lt;/strong&gt; edit resources.&lt;/p&gt;

&lt;h2 id=&quot;set-up-validation-rules&quot;&gt;Set Up Validation Rules&lt;/h2&gt;
&lt;p&gt;The new form request class has an &lt;code class=&quot;highlighter-rouge&quot;&gt;authorize()&lt;/code&gt; and a &lt;code class=&quot;highlighter-rouge&quot;&gt;rules()&lt;/code&gt; method stubbed out. The &lt;code class=&quot;highlighter-rouge&quot;&gt;authorize()&lt;/code&gt; method can be used to check if the user is authorized to make the request - we might add a check for article ownership here.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;rules()&lt;/code&gt; method allows you to set rules which must be passed. The controller form processing method will receive an instance of the request class - and will not progress if any rules fail.&lt;/p&gt;

&lt;h2 id=&quot;example-rules-with-custom-error-messages&quot;&gt;Example Rules with Custom Error Messages&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// app/Http/Requests/CreateArticleRequest.php
&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;sd&quot;&gt;/**
   * Get the validation rules that apply to the request.
   *
   * This method should return an array of validation rules.
   *
   * @return array
   */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rules&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// The 'title' field is required and must be at least 10 characters
&lt;/span&gt;        &lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'required|min:10'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// The 'body' field is required
&lt;/span&gt;        &lt;span class=&quot;s1&quot;&gt;'body'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'required'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// The 'published_at' field is required and must be a date
&lt;/span&gt;        &lt;span class=&quot;s1&quot;&gt;'published_at'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'required|date'&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;// If necessary, create a $rules array to return (rather than returning
&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// the array directly). This will allow conditional validation to be
&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// built in - for example, a form that updates a record may require
&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// additional (or relaxed) validation rules. These can be added
&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// conditionally to the $rules array before it is returned.
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;sd&quot;&gt;/**
     * Override the built-in messages.
     *
     * @return array
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;messages&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'title.required'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Er, you forgot to add a title!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'title.min'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Don\'t be stingy - make the title LONGER THAN 3 CHARACTERS!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'body.required'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'No body, no article.'&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;in-the-controller&quot;&gt;In the Controller&lt;/h2&gt;
&lt;p&gt;The new form request instance is passed into form processing methods on the Controller.&lt;/p&gt;

&lt;p&gt;Dependency injection happens automatically by means of Laravel’s service container, but this can only take place if the request class is type-hinted on the controller method.&lt;/p&gt;

&lt;p&gt;The store/update methods will not proceed until validation rules pass.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// app/Http/Controllers/ArticlesController.php
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;sd&quot;&gt;/**
   * Store a newly created resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @return \Illuminate\Http\Response
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Requests\ArticleRequest&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$request&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;nv&quot;&gt;$request&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;Article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'articles'&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;o&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/validation&quot;&gt;Laravel Docs: Validation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/validation#available-validation-rules&quot;&gt;Available Validation Rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 22 Sep 2016 16:37:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/laravel-form-validation-primer/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/laravel-form-validation-primer/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Accessors - Format or Prepare Data for Access</title>
        <description>&lt;p&gt;Laravel Accessors are Model methods that allow Eloquent attributes to be formatted or processed when they are retrieved.&lt;/p&gt;

&lt;p&gt;To set up an Accessor, add a suitable method in the Model class. The database column is determined by the method name, which hence needs to be in a certain format:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;get{ColumnName}Attribute&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note that the column name needs to be written in StudlyCaps (PascalCase) - the first letter of each sub-word (including the first) is capitalised.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An accessor that takes a string saved in the &lt;code class=&quot;highlighter-rouge&quot;&gt;post_title&lt;/code&gt; column and converts it to uppercase in the Eloquent attribute would look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getPostTitleAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&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;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'post_title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;strtoupper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The method receives the value of the attribute, and is automatically called when the value of the attribute is retrieved.&lt;/p&gt;

&lt;p&gt;In the view for this example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;@foreach($posts as $post)
  &amp;lt;h2&amp;gt;{{$post-&amp;gt;title}}&amp;lt;/h2&amp;gt;
@endforeach&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…titles will be capitailsed.&lt;/p&gt;

&lt;p&gt;When the attribute is accessed, it will be in uppercase. The string stored in the database remains unchanged.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/eloquent-mutators#accessors-and-mutators&quot;&gt;Laravel Docs: Accessors &amp;amp; Mutators&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 21 Sep 2016 10:56:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/laravel-accessors-format-or-prepare-data-for-access/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/laravel-accessors-format-or-prepare-data-for-access/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Mutators</title>
        <description>&lt;p&gt;Laravel mutators are Model methods that process data in some way before it is stored in the database.&lt;/p&gt;

&lt;p&gt;Potential use cases:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Capitalising names before saving&lt;/li&gt;
  &lt;li&gt;Title-casing titles&lt;/li&gt;
  &lt;li&gt;Slugifying slugs&lt;/li&gt;
  &lt;li&gt;Change date strings to &lt;code class=&quot;highlighter-rouge&quot;&gt;Carbon&lt;/code&gt; objects&lt;/li&gt;
  &lt;li&gt;Hashing passwords&lt;/li&gt;
  &lt;li&gt;JSON encoding (possible in MySQL 5.7.8, coming soon in MariaDB)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To set up a Mutator, add a suitable method in the Model class. The database column is determined by the method name, which hence needs to be in a certain format:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;set{ColumnName}Attribute&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note that the column name needs to be written in StudlyCaps (PascalCase) - the first letter of each sub-word (including the first) is capitalised.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A mutator that converts a string to title case, saved in the &lt;code class=&quot;highlighter-rouge&quot;&gt;post_title&lt;/code&gt; column would look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setPostTitleAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&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;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'post_title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ucwords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the method doesn’t return anything - it just directly accesses the atribute and “mutates” the value.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://laravel.com/docs/5.3/eloquent-mutators#introduction&quot;&gt;Laravel Docs, Mutators&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bosnadev.com/2015/12/17/laravel-accessors-mutators/&quot;&gt;Good article on Accessors and Mutators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 21 Sep 2016 09:48:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/laravel-accessors-and-mutators/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/laravel-accessors-and-mutators/</guid>
      </item>
      
    
      
      <item>
        <title>Resource Routes - RESTful Routes in Laravel</title>
        <description>&lt;p&gt;Laravel allows you to quickly and easily set up controllers and routes so that you can interact with data in a RESTful way..&lt;/p&gt;

&lt;h2 id=&quot;create-a-model-and-database-table&quot;&gt;Create a Model and Database Table&lt;/h2&gt;

&lt;p&gt;Create a Model in the usual way (the &lt;code class=&quot;highlighter-rouge&quot;&gt;-m&lt;/code&gt; flag creates a migration for the model, allowing you to set up a new database table):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;php artisan make:model Article -m&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Amend the migration as necessary and run &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan migrate&lt;/code&gt; to set up the new table.&lt;/p&gt;

&lt;h2 id=&quot;create-a-resourceful-controller&quot;&gt;Create a Resourceful Controller&lt;/h2&gt;
&lt;p&gt;Create a controller using Artisan using the &lt;code class=&quot;highlighter-rouge&quot;&gt;--resource&lt;/code&gt; option:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;php artisan make:controller ArticleController --resource&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This creates a new controller under &lt;code class=&quot;highlighter-rouge&quot;&gt;app/Http/Controllers&lt;/code&gt;, with stubbed out methods to allow interaction with the database table for this resource:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;index()&lt;/code&gt;: Display a listing view for the resource&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;create()&lt;/code&gt;: Show the form for creating a new resource&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;store()&lt;/code&gt;: Store a newly created resource in storage&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;show()&lt;/code&gt;: Display the specified resource&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;edit()&lt;/code&gt;: Update the specified resource in storage&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;destroy()&lt;/code&gt;: Remove the specified resource from storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ruby on Rails has avery similar command: &lt;code class=&quot;highlighter-rouge&quot;&gt;rails g scaffold_controller Article&lt;/code&gt; - which stubs out a similar controller.&lt;/p&gt;

&lt;h2 id=&quot;create-route-for-the-resource&quot;&gt;Create Route for the Resource&lt;/h2&gt;
&lt;p&gt;In your &lt;code class=&quot;highlighter-rouge&quot;&gt;routes/web.php&lt;/code&gt; file (Laravel 5.3), create a new route using the &lt;code class=&quot;highlighter-rouge&quot;&gt;resource()&lt;/code&gt; method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;Route::resource('articles', 'ArticleController');&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you check the registered routes now using &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan route:list&lt;/code&gt;, you’ll see the new (named) routes automatically set up:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;+--------+-----------+-------------------------+------------------+------------------------------------------------+--------------+
| Domain | Method    | URI                     | Name             | Action                                         | Middleware   |
+--------+-----------+-------------------------+------------------+------------------------------------------------+--------------+

|        | GET|HEAD  | articles                | articles.index   | App\Http\Controllers\ArticleController@index   | web          |
|        | POST      | articles                | articles.store   | App\Http\Controllers\ArticleController@store   | web          |
|        | GET|HEAD  | articles/create         | articles.create  | App\Http\Controllers\ArticleController@create  | web          |

|        | GET|HEAD  | articles/{article}      | articles.show    | App\Http\Controllers\ArticleController@show    | web          |
|        | PUT|PATCH | articles/{article}      | articles.update  | App\Http\Controllers\ArticleController@update  | web          |
|        | DELETE    | articles/{article}      | articles.destroy | App\Http\Controllers\ArticleController@destroy | web          |
|        | GET|HEAD  | articles/{article}/edit | articles.edit    | App\Http\Controllers\ArticleController@edit    | web          |&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The resource has been set up so that the correct controller methods are triggered when you access a specified route with a given HTTP verb.&lt;/p&gt;
</description>
        <pubDate>Mon, 19 Sep 2016 14:36:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/resource-routes-restful-routes-in-laravel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/resource-routes-restful-routes-in-laravel/</guid>
      </item>
      
    
      
      <item>
        <title>Mount and Transfer Data From an Encrypted Filesystem in Ubuntu</title>
        <description>&lt;p&gt;This article describes the steps necessary to recover data from a LUKS encrypted filesystem under Ubuntu 16.04. We needed to also move encrypted user home directories.&lt;/p&gt;

&lt;p&gt;Mount the old encrypted disk:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Identify the LUKS encrypted volume&lt;/li&gt;
  &lt;li&gt;Open device/decrypt&lt;/li&gt;
  &lt;li&gt;Mount the decrypted filesystem&lt;/li&gt;
  &lt;li&gt;Copy data from source to destination&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;mount-encrypted-lvm-logical-volume&quot;&gt;Mount Encrypted LVM Logical Volume&lt;/h2&gt;

&lt;p&gt;Identify the encrypted device:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo fdisk -l

&lt;span class=&quot;c&quot;&gt;# Follow with:&lt;/span&gt;
sudo lsblk -f /dev/sdb

sudo file -s /dev/sdb3

&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
/dev/sdb3: LUKS encrypted file, ver 1 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;aes, xts-plain64, sha256] UUID: xxxx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;open-the-encrypted-device&quot;&gt;Open the Encrypted Device&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cryptsetup luksOpen /dev/sdb3 encrypted_device
&lt;span class=&quot;c&quot;&gt;# This returns:&lt;/span&gt;
Enter passphrase &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; /dev/sdb3:

&lt;span class=&quot;c&quot;&gt;# Enter the encryption passphrase at this point&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You then need to identify the volume group and list logical volumes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo vgdisplay --short

&lt;span class=&quot;c&quot;&gt;# Typical return:&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;ubuntu-vg&quot;&lt;/span&gt; 464.78 GiB &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;464.78 GiB used / 0    free]

&lt;span class=&quot;c&quot;&gt;# List logical volumes:&lt;/span&gt;
sudo lvs -o lv_name,lv_size -S &lt;span class=&quot;nv&quot;&gt;vg_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ubuntu-vg

&lt;span class=&quot;c&quot;&gt;# Typical return:&lt;/span&gt;
LV     LSize
  root   456.86g
  swap_1   7.91g&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;At this point, you may hit trouble - if you are working on a Ubuntu logical and trying to mount a Ubuntu logical volume, it’s likely that they’ll have the same volume group name (“ubuntu-vg”).&lt;/p&gt;

&lt;p&gt;To fix this, you can rename one of the volumes - &lt;strong&gt;but beware - this may prevent that disk from booting without major intervention&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rename the logical volume:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Get the UUID&lt;/span&gt;
sudo vgdisplay

&lt;span class=&quot;c&quot;&gt;# Typical return&lt;/span&gt;
--- Volume group ---
  VG Name               ubuntu-vg

  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             &lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt;/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               464.78 GiB
  PE Size               4.00 MiB
  Total PE              118983
  Alloc PE / Size       118983 / 464.78 GiB
  Free  PE / Size       0 / 0
  VG UUID               xxxx

&lt;span class=&quot;c&quot;&gt;# Rename by referencing the Volume Group UUID:&lt;/span&gt;
sudo vgrename -v XcFAZ7-3iBG-BnQ7-GoS4-egLP-29YY-u8mcXY old-drive

&lt;span class=&quot;c&quot;&gt;# The volume group is now &quot;old-drive&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You then need to activate the desired volume group - in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;root&lt;/code&gt; on &lt;code class=&quot;highlighter-rouge&quot;&gt;old-drive&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Check the new volume name&lt;/span&gt;
sudo vgdisplay --short

&lt;span class=&quot;c&quot;&gt;# Check the logical volumes on this volumne&lt;/span&gt;
sudo lvs -o lv_name,lv_size -S &lt;span class=&quot;nv&quot;&gt;vg_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;old-drive

&lt;span class=&quot;c&quot;&gt;# Activate the desired root&lt;/span&gt;
sudo lvchange -ay old-drive/root&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;mount-the-encrypted-filesystem&quot;&gt;Mount the Encrypted Filesystem&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir /mnt/old-drive
sudo mount /dev/old-drive/root /mnt/old-drive&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The decrypted filesystem is now available under &lt;code class=&quot;highlighter-rouge&quot;&gt;/mnt/old-drive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our case, this system contains user home directories that are also encrypted. These need to be moved to &lt;code class=&quot;highlighter-rouge&quot;&gt;/home&lt;/code&gt; on the destination filesystem.&lt;/p&gt;

&lt;p&gt;On the new filesystem, don’t create users. First, move the encrypted directories to the usual location. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Move a user home directory&lt;/span&gt;
sudo rsync -ra --progress /mnt/old-drive/home/rory /home

&lt;span class=&quot;c&quot;&gt;# Also move the Apache root directory:&lt;/span&gt;
sudo mkdir -p /var/www
sudo rsync -ra --progress /mnt/old-drive/var/www/html /var/www&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then create corresponding users. The &lt;code class=&quot;highlighter-rouge&quot;&gt;-m&lt;/code&gt; flag on &lt;code class=&quot;highlighter-rouge&quot;&gt;useradd&lt;/code&gt; denotes that a home directory will be created if one doesn’t already exist. In our case, we’ve just created the directory by moving the old one into position from the old drive.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Create the user &quot;rory&quot;&lt;/span&gt;
sudo useradd -m rory
sudo passwd rory
sudo adduser rory sudo&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The user can now log on using their exisiting passphrase for decryption.&lt;/p&gt;

&lt;h2 id=&quot;grub-problems&quot;&gt;GRUB Problems&lt;/h2&gt;
&lt;p&gt;I encountered a major problem when completing this - GRUB became borked and the system would not boot - it hung on a initramfs prompt (which was pretty useless - don’t waste time in this limited shell).&lt;/p&gt;

&lt;p&gt;The Initramfs prompt suggests that GRUB 2 began the boot process (the initial Ubuntu loading screen was visible) - but couldn’t pass control to the OS.&lt;/p&gt;

&lt;p&gt;In our case, I suspect this was related to renaming the logical volume on the old disk.&lt;/p&gt;

&lt;p&gt;The solution involved:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Booting Ubuntu from a live disk&lt;/li&gt;
  &lt;li&gt;Decrypting and mounting the main volume&lt;/li&gt;
  &lt;li&gt;Downloading and running ‘boot-repair’&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;boot-repair&lt;/code&gt; on an encrypted volume requires a bit of work - the volume needs to be properly decrypted and activated. In particular, you need to &lt;strong&gt;activate the encrypted drive using the correct name&lt;/strong&gt; - I determined this by trial and error, with some clues from &lt;a href=&quot;https://www.andrewferrier.com/blog/2012/09/24/fixing-initrd-to-regain-ubuntu-encrypted-root-prompt-on-boot/&quot;&gt;this useful article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The procedure:&lt;/p&gt;

&lt;p&gt;In the live environment, navigate to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/crypttab&lt;/code&gt; and take a peek:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cat /etc/crypttab

&lt;span class=&quot;c&quot;&gt;# Typical output:&lt;/span&gt;
sdb3_crypt &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;xxxxx none luks,discard
cryptswap1 &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;xxxxx /dev/urandom swap,offset&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1024,cipher&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;aes-xts-plain64&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This gives you the name that you need for your cryptsetup - in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;sdb3_crypt&lt;/code&gt;. Decrypt the volume using this name:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;cryptsetup luksOpen /dev/sdb3 sdb3_crypt
&lt;span class=&quot;c&quot;&gt;# Enter decryption passphrase&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Activate:&lt;/span&gt;
sudo lvchange -ay sdb3_crypt/root&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then download and run Boot Repair - this should allow you to reinstall GRUB 2:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; boot-repair&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.sleeplessbeastie.eu/2015/11/16/how-to-mount-encrypted-lvm-logical-volume/&quot;&gt;Article on mounting encrypted LVM logical volume&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/a/63598&quot;&gt;Mount Luks encrypted drive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/a/680808&quot;&gt;Changing the name of volume group&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/a/643426&quot;&gt;Create New User, exisiting home directory&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/Boot-Repair&quot;&gt;Boot Repair&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/Grub2/Troubleshooting&quot;&gt;GRUB2 Troubleshooting&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.andrewferrier.com/blog/2012/09/24/fixing-initrd-to-regain-ubuntu-encrypted-root-prompt-on-boot/&quot;&gt;Fixing intird&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 18 Sep 2016 16:15:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/mount-and-transfer-data-from-an-encrypted-filesystem-in-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/mount-and-transfer-data-from-an-encrypted-filesystem-in-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Check Site Backup Integrity: WordPress/PHP MySQL</title>
        <description>&lt;p&gt;If you’ve set up a backup solution for WordPress or other dynamic PHP websites, you will probably be backing up site files as well as the site database. For a proper backup solution, you need to check that the backup copy is viable.&lt;/p&gt;

&lt;p&gt;You may have a copy of the site files, along with a (hopefully properly) dumped database, but unless you connect these up, how do you know that your backup copy is sound?&lt;/p&gt;

&lt;p class=&quot;emphasis-block&quot;&gt;&lt;strong&gt;The integrity of your backups is not something that you should discover during an emergency recovery situation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Manually rebuilding a working copy of a dynamic website is time consuming. For each site database, internal site URLs all relate to production domains, complicating the rebuild process. When you have a server backup with ten or twenty important client sites, verification of backups looks pretty daunting - and I suspect that a lot of people just don’t bother.&lt;/p&gt;

&lt;p&gt;This article describes how to partially automate this process.&lt;/p&gt;

&lt;p&gt;If you want to hack on this, get the files &lt;a href=&quot;https://github.com/DavidCWebs/check-backups&quot;&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;In our case, site files from the Apache root of a production server are backed up incrementally on a daily basis to a date-stamped directory. This contains:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A subdirectory &lt;code class=&quot;highlighter-rouge&quot;&gt;html&lt;/code&gt; - which in turn contains a subdirectory for each site under the document root&lt;/li&gt;
  &lt;li&gt;A subdirectory &lt;code class=&quot;highlighter-rouge&quot;&gt;sql&lt;/code&gt; which contains a collection of dumped databases for the sites in question&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Important config files are also backed up, but that is beyond the scope of this article.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/06/incremental-backup-on-server/&quot;&gt;Production server backup procedure&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/06/secure-rsync-between-servers/&quot;&gt;Secure rsync between servers&lt;/a&gt; - describes consolidating backup copies on a central backup server&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/10/backup-rsync-between-devices/&quot;&gt;Rsync between backup server and local machine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article assumes that the backup has been downloaded to a local machine.&lt;/p&gt;

&lt;h2 id=&quot;checking-integrity-overview&quot;&gt;Checking Integrity: Overview&lt;/h2&gt;

&lt;p&gt;To test the integrity of backed up sites, one option is to build working clones of the sites on a virtual machine. To avoid the need to change URLs on the backup copies, the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; file is amended on the guest VM.&lt;/p&gt;

&lt;p&gt;Obviously, the guest VM needs to run a server that broadly matches the original backed up server (in this case Apache), and the virtual hosts settings for the guest VM server need to be set up correctly (this is a one-time import from the backed-up config directory).&lt;/p&gt;

&lt;p&gt;You don’t necessarily need to use a VM - you could use any machine on the local network. The reason this is done on a VM/separate machine is so that the main host computer can access the &lt;strong&gt;actual&lt;/strong&gt; live sites for maintenance purposes.&lt;/p&gt;

&lt;p&gt;This method also keeps seperation between backed up clones and ongoing development websites - which are two different things.&lt;/p&gt;

&lt;p&gt;This article assumes that a backup archive is available. Building working copies involves:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;One-time setup of a suitable Virtual Machine - in this case, a Ubuntu Xenial, Apache, MariaDB and PHP 7 LAMP stack&lt;/li&gt;
  &lt;li&gt;A one-time import of relevant database users to the VM&lt;/li&gt;
  &lt;li&gt;Exporting files from the Host machine backup archive to the Guest VM (run command in Host)&lt;/li&gt;
  &lt;li&gt;Importing databases in the Guest (run command in Guest)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;aims&quot;&gt;Aims&lt;/h2&gt;
&lt;p&gt;Check the integrity of multiple site backups by building working local copies. This is achieved by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Moving site files and databases for a backed-up production server from a host machine into a local virtual machine&lt;/li&gt;
  &lt;li&gt;Import MySQL/MariaDB databases and set up working sites on the VM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backup integrity should be checked regularly, so this should be a simple process.&lt;/p&gt;

&lt;p&gt;Ideally, once the system has been setup it should be run by administrators rather than developers.&lt;/p&gt;

&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;These BASH scripts have been tested on Ubuntu Xenial Xerus 16.04 Desktop.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://help.gnome.org/users/zenity/stable/intro.html.en&quot;&gt;Zenity&lt;/a&gt; is used to create user dialogues.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt; is required for the Virtual Machine. In this case, the VM runs Ubuntu 16.04 Xenial Xerus desktop - desktop rather than server because it allows easy checking of the moved sites. To achieve this, the guest machine hosts file (&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt;) must be set up properly to point at the local copies.&lt;/p&gt;

&lt;p&gt;The VM also runs Ubuntu 16.04 Desktop. The database server is MariaDB, but the commands would work on a standard MySQL database server.&lt;/p&gt;

&lt;p&gt;The sql backups directory includes the &lt;code class=&quot;highlighter-rouge&quot;&gt;performance_schema.sql&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;phpmyadmin.sql&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;mysql.sql&lt;/code&gt; and log files from the original server. These aren’t necessary to build clones from backups, and if imported will probably mess up the VM MySQL configuration. Because of this, we exclude these files from the transfer - see the &lt;code class=&quot;highlighter-rouge&quot;&gt;sql-verification-exclude&lt;/code&gt; file in the linked repo for an example.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note: For the backed up sites on the guest machine to work properly, the MySQL users from the original server should be imported in a one-time operation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;move-files-to-the-vm&quot;&gt;Move Files to the VM&lt;/h2&gt;
&lt;p&gt;This is achieved with the &lt;code class=&quot;highlighter-rouge&quot;&gt;move-backups&lt;/code&gt; script. This script prompts the user to choose a directory to move. The script is tightly coupled to our requirements, but would be easy to amend.&lt;/p&gt;

&lt;p&gt;The directory to be moved is a datestamped directory that contains the entire
&lt;code class=&quot;highlighter-rouge&quot;&gt;html&lt;/code&gt; directory (i.e. document root) from a backed-up Apache server. It also contains backed up MySQL files (originally created by &lt;code class=&quot;highlighter-rouge&quot;&gt;mysqldump&lt;/code&gt;) in a &lt;code class=&quot;highlighter-rouge&quot;&gt;sql&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2 id=&quot;move-backups-script&quot;&gt;Move Backups Script&lt;/h2&gt;
&lt;p&gt;Run on the Host computer.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Move a directory into a local Virtual Machine for testing purposes.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This file should be executable and in your path. E.g.:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - `mv move-backups /usr/local/bin`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - `chmod +x /usr/local/bin/move-backups`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Run: `move-backups`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Add username@network-IP for your VM in place of `david@192.168.1.145`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Add root@network-IP for your VM in place of `root@192.168.1.145`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;STORAGE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/media/david/storage/servername
&lt;span class=&quot;nv&quot;&gt;SQL_DESTINATION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;david@192.168.1.145:staging
&lt;span class=&quot;nv&quot;&gt;HTML_DESTINATION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;root@192.168.1.145:/var/www/html
&lt;span class=&quot;nv&quot;&gt;VM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Xenial
&lt;span class=&quot;nv&quot;&gt;SQL_EXCLUDE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/media/david/storage/sql-verification-exclude &lt;span class=&quot;c&quot;&gt;# rsync excludes are controlled in a file&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$STORAGE&lt;/span&gt;;

&lt;span class=&quot;c&quot;&gt;# Select the Directory to move&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
zenity --info &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Begin the build process for backup up client websites. Click &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;OK&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; to begin. Then select the date-stamped directory in the backup storage area.&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;SOURCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;zenity --file-selection --directory --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Select a Directory to Sync&quot;&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in
  &lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SOURCE&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;No file selected.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
  -1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;An unexpected error has occurred.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Start the Virtual Machine - for headless, append --type headless&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
VBoxManage startvm &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; --type headless | zenity --progress &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --pulsate --width&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;320&quot;&lt;/span&gt; --height&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;150&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Starting &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Virtual Machine&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Please Wait while &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; is started&quot;&lt;/span&gt; --auto-close

&lt;span class=&quot;c&quot;&gt;# Sync HTML directories INDIVIDUALLY&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HTML_DIRS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SOURCE&lt;/span&gt;/html&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Loop through Directories only&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;DIR &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$HTML_DIRS&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;/; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# For our rsync setup, the source directory MUST NOT have a trailing slash -&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# so that if the directory doesn't exist, it will be created.&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# basename of the $DIR - used as the destination directory, under `/var/www/html`&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;DEST_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;nv&quot;&gt;$DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

  rsync -azv --progress --delete &lt;span class=&quot;nv&quot;&gt;$SOURCE_DIR&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$HTML_DESTINATION&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$DEST_DIR&lt;/span&gt; | zenity --progress &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --pulsate --width&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;320&quot;&lt;/span&gt; --height&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;150&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Syncing the HTML directory: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Please Wait&quot;&lt;/span&gt; --auto-close

&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Sync SQL backups to a staging directory&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rsync -azv --exclude-from&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SQL_EXCLUDE&lt;/span&gt; --progress --delete &lt;span class=&quot;nv&quot;&gt;$SOURCE&lt;/span&gt;/sql/ &lt;span class=&quot;nv&quot;&gt;$SQL_DESTINATION&lt;/span&gt;/sql | zenity --progress &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --pulsate --width&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;320&quot;&lt;/span&gt; --height&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;150&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Syncing the SQL directory&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Please Wait&quot;&lt;/span&gt; --auto-close

&lt;span class=&quot;c&quot;&gt;# Tidy up&lt;/span&gt;
zenity --question &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Sync complete. Do you want to shut down the VM?&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in

  &lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Close up the VM, maintain state&lt;/span&gt;
  VBoxManage controlvm &lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt; savestate | zenity --progress &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --pulsate --width&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;320&quot;&lt;/span&gt; --height&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;150&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Shutting down &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; Virtual Machine&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Please Wait while VMs are Saved&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --auto-close
    zenity --info&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
     --window-icon&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
     --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The VM &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; has been shut down.&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$vm&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; was closed to a saved state&quot;&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;

  1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt;
  zenity --info&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --window-icon&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  --text&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Your VM &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$VM&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; is Running - though it may be in a headless[GitHub repo with scripts](https://github.com/DavidCWebs/check-backups).

  -1)
  echo &quot;&lt;/span&gt;An unexpected error has occurred.&lt;span class=&quot;s2&quot;&gt;&quot;
  ;;

esac
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Usage:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add &lt;code class=&quot;highlighter-rouge&quot;&gt;move-backups&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;usr/local/bin&lt;/code&gt; on the Host computer: &lt;code class=&quot;highlighter-rouge&quot;&gt;mv move-backups /usr/local/bin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make executable: &lt;code class=&quot;highlighter-rouge&quot;&gt;chmod +x /usr/local/bin/move-backups&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;move-backups&lt;/code&gt; in a terminal and follow instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When prompted, you should select a directory that contains the backed-up &lt;code class=&quot;highlighter-rouge&quot;&gt;html&lt;/code&gt;
directory from the Apache doc root - the directory that is normally located
at &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/&lt;/code&gt; in a standard Apache setup.&lt;/p&gt;

&lt;p&gt;Note that the moved files won’t do anything unless you also import the
associated databases on the guest machine.&lt;/p&gt;

&lt;h2 id=&quot;import-databases&quot;&gt;Import Databases&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Add &lt;code class=&quot;highlighter-rouge&quot;&gt;import-databases&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;usr/local/sbin&lt;/code&gt; on the Guest computer/VM: &lt;code class=&quot;highlighter-rouge&quot;&gt;mv import-databases /usr/local/sbin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make executable: &lt;code class=&quot;highlighter-rouge&quot;&gt;chmod +x /usr/local/sbin/import-databases&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo import-databases&lt;/code&gt; in a terminal on the Guest VM&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The purpose of this script is to import databases so that working copies of&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# backed up PHP/WordPress websites can be quickly and easily checked.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The script loops through all databases in a staging directory and imports them&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# into MySQL/MariaDB. Existing databases having the same name will be overwritten.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#-------------------------------------------------------------------------------&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;SOURCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/david/staging/sql
&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;thenicelongpassword
&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SOURCE&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; i &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0; i &amp;lt; &lt;span class=&quot;k&quot;&gt;${#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;; i++ &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# The file extension - in our case, there are *.log files that should be ignored&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;EXT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]#*.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sql&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$EXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DB_SOURCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;DB_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; .sql&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# If a Databse exists with this name, DROP it&lt;/span&gt;
    mysql --user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;root --password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;DROP DATABASE IF EXISTS &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DB_NAME&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Create new DB with the name of the DB backup file&lt;/span&gt;
    mysql --user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;root --password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;create database &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DB_NAME&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; GRANT ALL PRIVILEGES ON &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DB_NAME&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\`&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.* TO root@localhost IDENTIFIED BY '&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;'&quot;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Import the Database&lt;/span&gt;
    mysql --user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;root --password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DB_NAME&lt;/span&gt; &amp;lt; &lt;span class=&quot;nv&quot;&gt;$DB_SOURCE&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;fi

done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set proper ownership of site files&lt;/span&gt;
chown -R www-data /var/www/html/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;todo&quot;&gt;TODO&lt;/h2&gt;
&lt;p&gt;These scripts are a good start, and allow us to build and check backup copies quite easily. There is room for further automation - ideally we’d like the process to be fully automated, integrated naturally into the backup process.&lt;/p&gt;

&lt;p&gt;Our setup includes passwordless SSH keys which allows for easier rsync’ing, and this has not been documented.&lt;/p&gt;

&lt;p&gt;Other enhancements might include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Prevent selection of the ‘wrong’ backup directory&lt;/li&gt;
  &lt;li&gt;Auto creating the staging directory for the sql files transfer&lt;/li&gt;
  &lt;li&gt;Trigger the &lt;code class=&quot;highlighter-rouge&quot;&gt;import-databases&lt;/code&gt; script from the host, so working copies are built with a single command&lt;/li&gt;
  &lt;li&gt;Better feedback on the &lt;code class=&quot;highlighter-rouge&quot;&gt;import-databases&lt;/code&gt; script (there’s none at the moment!)&lt;/li&gt;
  &lt;li&gt;Document how to import users from original server to the guest machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/DavidCWebs/check-backups&quot;&gt;Pull requests welcome&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DavidCWebs/check-backups&quot;&gt;GitHub repo with scripts&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/manual/ch08.htmlvboxmanage-controlvm&quot;&gt;Closing the VM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/10274182&quot;&gt;Get path of a filename&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/manual/ch08.htmlvboxmanage-startvm&quot;&gt;Starting the VM from a script&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/19485757&quot;&gt;Remove trailing slash&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ubuntuforums.org/archive/index.php/t-1078689.html&quot;&gt;VM Management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 16 Sep 2016 11:28:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/verifying-backups-of-wordpress-websites/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/verifying-backups-of-wordpress-websites/</guid>
      </item>
      
    
      
      <item>
        <title>Display WordPress Term Links</title>
        <description>&lt;p&gt;Display a list of links to associated WordPress terms for a given taxonomy/custom taxonomy.&lt;/p&gt;

&lt;p&gt;Two options for class methods to achieve this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

  &lt;span class=&quot;sd&quot;&gt;/**
   * Output post term links.
   *
   * The `get_the_terms()` function returns an array of term objects for the
   * given taxonomy.
   *
   * @uses get_the_terms()
   * @param  string The custom taxonomy to target
   * @return string HTML markup for a list of term links
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;the_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$taxonomy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'category'&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;nv&quot;&gt;$terms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_the_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;post_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$taxonomy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nb&quot;&gt;ob_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$terms&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$term&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;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;a href=&quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_term_link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&quot;&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/a&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$terms&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;, &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Comma separated, but not last item
&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ob_get_clean&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;sd&quot;&gt;/**
   * Alternative method.
   *
   * The `wp_get_object_terms()` function retrieves the terms associated with
   * the given object(s) for the specified taxonomy.
   *
   * @uses wp_get_object_terms()
   * @param  string The custom taxonomy to target
   * @return string HTML markup for a list of term links
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alt_post_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'category'&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;nv&quot;&gt;$post_terms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_get_object_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;post_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'fields'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ids'&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_terms&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_wp_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_terms&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;p&quot;&gt;{&lt;/span&gt;

      &lt;span class=&quot;nv&quot;&gt;$term_ids&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_terms&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;nv&quot;&gt;$terms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_list_categories&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;s1&quot;&gt;'title_li'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'style'&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'none'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'echo'&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'taxonomy'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'include'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$term_ids&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;nv&quot;&gt;$terms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rtrim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str_replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;br /&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$terms&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;s1&quot;&gt;','&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$terms&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You could also simply drop this into the template, within the loop to return a list of links to ‘project-category’ terms for the current post:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_the_term_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'project-category'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Project Categories: '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;', '&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Function_Reference/wp_get_object_terms&quot;&gt;Codex: wp_get_object_terms()&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.wordpress.org/reference/functions/get_the_terms/&quot;&gt;get_the_terms()&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Function_Reference/get_the_term_list&quot;&gt;get_the_term_list()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 15 Sep 2016 14:28:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/display-wordpress-term-links/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/display-wordpress-term-links/</guid>
      </item>
      
    
      
      <item>
        <title>Target the Last Item in a PHP foreach Loop</title>
        <description>&lt;p&gt;To target the last item in a PHP foreach loop without using a counter, check for &lt;code class=&quot;highlighter-rouge&quot;&gt;count( $array ) -1&lt;/code&gt; within the loop.&lt;/p&gt;

&lt;p&gt;This simple example assigns appropriate classes to the rendered elements:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$array&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&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;nv&quot;&gt;$class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$array&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; class='not-last'&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; class='last'&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;div&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$class&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$value['the_title']&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;/div&amp;gt;&quot;&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 15 Sep 2016 11:53:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/target-the-last-item-in-a-php-foreach-loop/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/target-the-last-item-in-a-php-foreach-loop/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Pagination with WP_Query - Page Slug Causing Error</title>
        <description>&lt;p&gt;Pagination can be tricky. This post outlines a problem that can arise due to a  page slug that conflicts with a custom post type rewrite base.&lt;/p&gt;

&lt;p&gt;Hopefully this post will help me to avoid repeating the error in a months time (I’ve just spent an hour fixing this). If you find this post after a Google search for “WordPress pagination 404 error on page 2” - hopefully you’ll find it useful.&lt;/p&gt;

&lt;h2 id=&quot;scenario&quot;&gt;Scenario&lt;/h2&gt;
&lt;p&gt;A static page that calls &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query()&lt;/code&gt; to build a custom loop. In this case, the page is called ‘People’ (the page slug is ‘people’) and &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query()&lt;/code&gt; builds a loop of ‘person’ custom post types.&lt;/p&gt;

&lt;p&gt;Pagination works, but clicking the link to “page 2” results in a 404 error.&lt;/p&gt;

&lt;h2 id=&quot;the-custom-loop&quot;&gt;The Custom Loop&lt;/h2&gt;
&lt;p&gt;I use a wrapper to simplify generation of &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rather than hunt through the wrapper classes (which apply overrides by merging arrays), it’s usually easiest to check the arguments passed in to &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query()&lt;/code&gt; by examining them just before they are used:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Log the args to `debug.log`
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;error_log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$args&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;c1&quot;&gt;// The Custom Query
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$custom_query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;\WP_Query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This outputs the arguments to &lt;code class=&quot;highlighter-rouge&quot;&gt;debug.log&lt;/code&gt;. Your site must be configured to log errors - your config should include this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'WP_DEBUG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'WP_DEBUG_LOG'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…and &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-content/debug.log&lt;/code&gt; should be writable by your server process. In my case (Ubuntu 16.04, Apache 2.4), the file should be owned by &lt;code class=&quot;highlighter-rouge&quot;&gt;www-data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Arguments passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query()&lt;/code&gt; in this case are as follows (JSON encoded for readability):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;post_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;person&quot;&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;nt&quot;&gt;&quot;post_status&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;publish&quot;&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;nt&quot;&gt;&quot;posts_per_page&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&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;nt&quot;&gt;&quot;order&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ASC&quot;&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;nt&quot;&gt;&quot;orderby&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;menu_order&quot;&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;nt&quot;&gt;&quot;nopaging&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&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;nt&quot;&gt;&quot;paged&quot;&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;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;These aruments look pretty OK to me.&lt;/p&gt;

&lt;h2 id=&quot;the-permalink&quot;&gt;The Permalink&lt;/h2&gt;
&lt;p&gt;Switching permalinks to WP plain option fixes the issue. &lt;strong&gt;This is a clue.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s not a solution, because the URLs look terrible.&lt;/p&gt;

&lt;h2 id=&quot;the-custom-post-type&quot;&gt;The Custom Post Type&lt;/h2&gt;
&lt;p&gt;In this case, the custom post type “person” had a rewrite rule so that the individual custom post type URLs were: http://example.com/people/joe-bloggs/.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And that’s the issue right there.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can verify this by temporarily amending the page slug for the static page that calls the custom loop. Do this so that is is anything other than ‘people’ and pagination will work.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;Options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Amend the rewrite rule for the custom post type&lt;/li&gt;
  &lt;li&gt;Amend the page slug&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I went with option 1. The client can live with http://example.com/person/joe-bloggs - the whole point of the static page with custom loop is to have a more controllable (pseudo) archive page, so the rewrite is pretty redundant - the http://example.com/people was originally set up as a more semantically meaningful archive URL.&lt;/p&gt;
</description>
        <pubDate>Wed, 14 Sep 2016 20:16:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/wordpress-pagination-with-wp-query-page-slug-causing-error/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/wordpress-pagination-with-wp-query-page-slug-causing-error/</guid>
      </item>
      
    
      
      <item>
        <title>Upgrading Letsencrypt Auto to Certbot</title>
        <description>&lt;p&gt;To upgrade from an older LetsEncrypt to Certbot on Ubuntu 14.04, install Certbot and run the auto-upgrading script.&lt;/p&gt;

&lt;h2 id=&quot;install-certbot&quot;&gt;Install Certbot&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Move the script to a suitable location:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mv certbot-auto /opt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;run-the-installer&quot;&gt;Run the Installer&lt;/h2&gt;
&lt;p&gt;Move into the containing directory and run the installer:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /opt
./certbot-auto&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;renew-certs&quot;&gt;Renew Certs&lt;/h2&gt;
&lt;p&gt;Certbot picks up on existing configurations pretty well. To run the auto-renew dialog:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ./certbot-auto renew

&lt;span class=&quot;c&quot;&gt;# or:&lt;/span&gt;

sudo ./certbot-auto renew --dry-run&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This brings up an ncurses window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note that all domains on the server will be pre-selected for domain renewal.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Be careful here - if you inadvertently leave a domain selected where the site hasn’t been set up for SSL, you can end up with a broken site. This is because all internal links will be pointing to the “http://” version, and Certbot will have created and enabled a vhosts configuration for the “https://” version.&lt;/p&gt;

&lt;p&gt;After selecting domains for cert renewal/registration, you will also get the option to choose whether HTTPS access is required or optional. “Required” is generally a good choice.&lt;/p&gt;

&lt;p&gt;Success message:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2016-12-12. To obtain a new or tweaked version of
   this certificate &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the future, simply run certbot-auto again with
   the &lt;span class=&quot;s2&quot;&gt;&quot;certonly&quot;&lt;/span&gt; option. To non-interactively renew &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;all&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; of your
   certificates, run &lt;span class=&quot;s2&quot;&gt;&quot;certbot-auto renew&quot;&lt;/span&gt;
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let&lt;span class=&quot;s1&quot;&gt;'s Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 13 Sep 2016 20:38:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/upgrading-letsencrypt-auto-to-certbot/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/upgrading-letsencrypt-auto-to-certbot/</guid>
      </item>
      
    
      
      <item>
        <title>PHP 7 Null Coalescing Operator</title>
        <description>&lt;p&gt;One of the goodies in PHP 7 is the null coalescing operator.&lt;/p&gt;

&lt;p&gt;This provides an easy method of setting a variable if it exists (i.e. is not null), or setting it to a default if null.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember - PHP 7 is required!&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;The expression (expr1) ?? (expr2) evaluates to expr2 if expr1 is NULL, and expr1 otherwise
— &lt;a href=&quot;http://php.net/manual/en/language.operators.comparison.php&quot;&gt;PHP Manual&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Null coalescing operator
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'baz'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// The pre PHP 7 way!
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])){&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bar'&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'baz'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...or pre-PHP 7 with a ternary:
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'baz'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is going to make setting defaults much neater and more readable.&lt;/p&gt;
</description>
        <pubDate>Sat, 10 Sep 2016 10:10:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/php-7-null-coalescing-operator/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/php-7-null-coalescing-operator/</guid>
      </item>
      
    
      
      <item>
        <title>Using Masonry With WordPress and Sage 8</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://masonry.desandro.com/&quot;&gt;Masonry&lt;/a&gt; is a very popular open-source grid layout library by David DeSandro. It provides a great way of laying out client images, especially when the sizes and aspect ratios are all over the place.&lt;/p&gt;

&lt;p&gt;You can use Masonry as a jQuery plugin, or initialize it with vanilla JavaScript - though I haven’t tried the latter.&lt;/p&gt;

&lt;p&gt;Installing Masonry when you’re using the Sage starter theme is probably best done with Bower. There are a few important issues that you need to be aware of.&lt;/p&gt;

&lt;p&gt;Most importantly, you need to reference the &lt;code class=&quot;highlighter-rouge&quot;&gt;masonry.pkgd.js&lt;/code&gt; file (rather than &lt;code class=&quot;highlighter-rouge&quot;&gt;masonry.js&lt;/code&gt;) from the Masonry bower package for the script to run properly.&lt;/p&gt;

&lt;h2 id=&quot;install-masonry-with-bower&quot;&gt;Install Masonry with Bower&lt;/h2&gt;
&lt;p&gt;In the project root, build Masonry with Bower:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bower install masonry --save
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You may also need the &lt;code class=&quot;highlighter-rouge&quot;&gt;imagesloaded&lt;/code&gt; plugin:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bower install imagesloaded --save
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;conditionally-load-masonry&quot;&gt;Conditionally Load Masonry&lt;/h2&gt;
&lt;p&gt;Masonry is generally only required on some pages, so we need to prevent masonry being auto-built into &lt;code class=&quot;highlighter-rouge&quot;&gt;main.js&lt;/code&gt; - to do this, we need to amend &lt;code class=&quot;highlighter-rouge&quot;&gt;assets/manifest.json&lt;/code&gt;:&lt;/p&gt;

&lt;h3 id=&quot;manifestjson&quot;&gt;manifest.json&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;dependencies&quot;&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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main.js&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;files&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;scripts/main.js&quot;&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;s2&quot;&gt;&quot;scripts/sticky-navbar.js&quot;&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;nt&quot;&gt;&quot;main&quot;&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;kc&quot;&gt;true&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;nt&quot;&gt;&quot;exclude&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;bower&quot;&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;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;outlayer&quot;&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;s2&quot;&gt;&quot;fizzy-ui-utils&quot;&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;s2&quot;&gt;&quot;get-size&quot;&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;s2&quot;&gt;&quot;ev-emitter&quot;&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;s2&quot;&gt;&quot;masonry&quot;&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;s2&quot;&gt;&quot;imagesloaded&quot;&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;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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;masonry.js&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;bower&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;masonry&quot;&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;s2&quot;&gt;&quot;imagesloaded&quot;&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;nt&quot;&gt;&quot;files&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;scripts/masonry-control.js&quot;&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;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…now the bower packages for masonry &amp;amp; imagesloaded, along with the &lt;code class=&quot;highlighter-rouge&quot;&gt;masonry-control.js&lt;/code&gt; script will be concatenated into &lt;code class=&quot;highlighter-rouge&quot;&gt;dist/masonry.js&lt;/code&gt;. This file can then be enqueued where it is needed.&lt;/p&gt;

&lt;h2 id=&quot;masonry-dependencies&quot;&gt;Masonry Dependencies&lt;/h2&gt;
&lt;p&gt;Masonry needs the &lt;code class=&quot;highlighter-rouge&quot;&gt;masonry.pkgd.js&lt;/code&gt; file to pull in necessary dependencies. Don’t try to do this manually - it will result in a mess.&lt;/p&gt;

&lt;p&gt;Instead set up an override in the project &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt;:&lt;/p&gt;

&lt;h3 id=&quot;bowerjson&quot;&gt;bower.json&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;overrides&quot;&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;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;bootstrap-sass&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;err&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;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;nt&quot;&gt;&quot;font-awesome&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main&quot;&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;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./scss/font-awesome.scss&quot;&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;s2&quot;&gt;&quot;./fonts/\*&quot;&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;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;masonry&quot;&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;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;main&quot;&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;s2&quot;&gt;&quot;./dist/masonry.pkgd.js&quot;&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;nt&quot;&gt;&quot;dependencies&quot;&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;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;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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;the-future-sage-9&quot;&gt;The Future: Sage 9&lt;/h2&gt;
&lt;p&gt;This article probably has a short shelf-life - Sage 9 is coming up, and this will drop Bower entirely - project dependencies will be managed by Webpack/NPM.&lt;/p&gt;
</description>
        <pubDate>Wed, 07 Sep 2016 09:46:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/09/using-masonry-with-wordpress-and-sage-8/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/09/using-masonry-with-wordpress-and-sage-8/</guid>
      </item>
      
    
      
      <item>
        <title>Laravel Models with Artisan</title>
        <description>&lt;p&gt;Laravel is an open source MVC framework for PHP. Laravel uses the concept of models to store and manage data. Laravel has a command line interface called &lt;code class=&quot;highlighter-rouge&quot;&gt;artisan&lt;/code&gt; that amongst other things allows you to easily set up model stubs. The framework uses the concept of “migrations” to manage changes to the app database - and migrations can be created in conjucntion with models.&lt;/p&gt;

&lt;h2 id=&quot;create-a-database&quot;&gt;Create a Database&lt;/h2&gt;
&lt;p&gt;If you don’t already have one set up, your project will need a database:&lt;/p&gt;

&lt;p&gt;Set up a new database with a unique user. Add database user credentials to Laravel’s &lt;code class=&quot;highlighter-rouge&quot;&gt;/.env&lt;/code&gt; file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Create Database&lt;/span&gt;
mysql -u root -p -e &lt;span class=&quot;s2&quot;&gt;&quot;create database new_DB; GRANT ALL PRIVILEGES ON new_DB.* TO new_DB_user@localhost IDENTIFIED BY 'nicelongpassword'&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-a-model&quot;&gt;Create a Model&lt;/h2&gt;
&lt;p&gt;To make a model called “Experiment”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:model Experiment&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Running this command stubs out a basic model under the &lt;code class=&quot;highlighter-rouge&quot;&gt;/app&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Make a model with a corresponding migration:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;php artisan make:model Experiment -m&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-db-tables&quot;&gt;Create DB Tables&lt;/h2&gt;
&lt;p&gt;Run the migrations to set up DB tables:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;migration-problems&quot;&gt;Migration Problems&lt;/h2&gt;
&lt;p&gt;Sometimes the migration fails because the &lt;code class=&quot;highlighter-rouge&quot;&gt;laravel.log&lt;/code&gt; file is not writable by the current user. It needs to be writable by the server user (&lt;code class=&quot;highlighter-rouge&quot;&gt;www-data&lt;/code&gt; in the case of Ubuntu/Apache), but the migration is run by your current user. You’ll get an error message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;david@david-desktop:$ &lt;/span&gt;php artisan migrate
PHP Fatal error: Uncaught UnexpectedValueException:
The stream or file &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/html/your-app/storage/logs/laravel.log&quot;&lt;/span&gt;
could not be opened: failed to open stream: Permission denied &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
/var/www/html/your-app/vendor/monolog/monolog/src/Monolog/Handler/
StreamHandler.php:107&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To fix this you could add your user’s primary group to the file ownership:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chown -R www-data:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; storage/logs/laravel.log

&lt;span class=&quot;c&quot;&gt;# Allow the file to be group-writable:&lt;/span&gt;
sudo chmod 664 storage/logs/laravel.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is probably pretty safe on a local development environment - and in most cases I think would be acceptable for production - you’re giving additional write access to your &lt;strong&gt;primary user only&lt;/strong&gt; after all - and if this user has been compromised, file permissions on a log file are the least of your worries.&lt;/p&gt;

&lt;p&gt;TODO: It would probably be better to set this up as an ACL as described in the &lt;a href=&quot;https://symfony.com/doc/current/setup/file_permissions.html&quot;&gt;Symfony documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://laraveldaily.com/how-to-create-migration-file-with-makemodel-command/&quot;&gt;Combined command for model &amp;amp; migration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://symfony.com/doc/current/setup/file_permissions.html#using-acl-on-a-system-that-supports-setfacl-linux-bsd&quot;&gt;Set up ACL in Ubuntu (Symfony)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 28 Aug 2016 11:52:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/new-laravel-models-and-migration/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/new-laravel-models-and-migration/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up &amp; Seed Laravel Database</title>
        <description>&lt;p&gt;These instructions are for local development of Laravel on Ubuntu 16.04 Xenial Xerus (Desktop). The instrauctions have been tested on 10.1.16-MariaDB, but they should also work for MySQL.&lt;/p&gt;

&lt;h2 id=&quot;create-database&quot;&gt;Create Database&lt;/h2&gt;
&lt;p&gt;Create a Database with a unique user:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql -u root -p -e &lt;span class=&quot;s2&quot;&gt;&quot;create database database_name; GRANT ALL PRIVILEGES ON database_name.* TO user_name@localhost IDENTIFIED BY 'urehfh577hg5hrpefh7'&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;connect-laravel&quot;&gt;Connect Laravel&lt;/h2&gt;

&lt;p&gt;Enter the Databse connection details in &lt;code class=&quot;highlighter-rouge&quot;&gt;.env&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;DB_CONNECTION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;mysql
&lt;span class=&quot;nv&quot;&gt;DB_HOST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;127.0.0.1
&lt;span class=&quot;nv&quot;&gt;DB_PORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3306
&lt;span class=&quot;nv&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;database_name
&lt;span class=&quot;nv&quot;&gt;DB_USERNAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;user_name
&lt;span class=&quot;nv&quot;&gt;DB_PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;urehfh577hg5hrpefh7&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;test-the-database&quot;&gt;Test the Database&lt;/h2&gt;
&lt;p&gt;Laravel comes with a couple of migrations defined out of the box.&lt;/p&gt;

&lt;p&gt;To check that Laravel is properly connected to the new database:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open a mysql prompt, working on the new DB:&lt;/span&gt;
mysql -u root -p database_name
&lt;span class=&quot;c&quot;&gt;# Enter show tables:&lt;/span&gt;
SHOW TABLES;
&lt;span class=&quot;c&quot;&gt;# Returns Empty set (0.00 sec)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Open a new terminal and run the pending Laravel migrations:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan migrate&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will run the default migrations (under Laravel 5.3, a “users” table and a “password_resets” table will be created, as well as a “migrations” table).&lt;/p&gt;

&lt;p&gt;You can also seed the database. Create a seeder class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan make:seeder UsersTableSeeder&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will create &lt;code class=&quot;highlighter-rouge&quot;&gt;database/seeds/UsersTableSeeder.php&lt;/code&gt;, which will be stubbed out with an empty &lt;code class=&quot;highlighter-rouge&quot;&gt;run()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;This method can be used to insert records into the database. Laravel includes the handy &lt;code class=&quot;highlighter-rouge&quot;&gt;Faker&lt;/code&gt; factory class, which allows dummy data to be created.&lt;/p&gt;

&lt;p&gt;To determine which fields to seed, check the table:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# At the mysql prompt:&lt;/span&gt;
SHOW COLUMNS FROM users;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;run()&lt;/code&gt; method of the seeder class that you’ve just created:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&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;nv&quot;&gt;$faker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Faker\Factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&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;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;o&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;nx&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'password'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bcrypt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'secret'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'email'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$faker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;email&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now, when you run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php artisan db:seed --class&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;UsersTableSeeder&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…the seeder will create 25 dummy users complete with realistic data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; running &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan db:seed&lt;/code&gt; will only run the default &lt;code class=&quot;highlighter-rouge&quot;&gt;DatabaseSeeder&lt;/code&gt; class - which will be empty. This is a bit different to the &lt;code class=&quot;highlighter-rouge&quot;&gt;php artisan migrate&lt;/code&gt;  command, which runs all migrations under the &lt;code class=&quot;highlighter-rouge&quot;&gt;database/migrations&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;To check the seeder results, run the following command from the mysql prompt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;SELECT &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; FROM users;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that Laravel has a much better way of interacting with your database on the fly - Artisan tinker:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Get the tinker prompt:&lt;/span&gt;
php artisan tinker

&lt;span class=&quot;c&quot;&gt;# Show all users:&lt;/span&gt;
App&lt;span class=&quot;se&quot;&gt;\U&lt;/span&gt;ser::all&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;-&amp;gt;toArray&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sat, 27 Aug 2016 18:53:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/set-up-and-seed-database-laravel/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/set-up-and-seed-database-laravel/</guid>
      </item>
      
    
      
      <item>
        <title>Install Laravel on Ubuntu 16.04 Desktop</title>
        <description>&lt;p&gt;This article describes how to get Laravel up and running in a Ubuntu Xenial Xerus development environment.&lt;/p&gt;

&lt;p&gt;Minimum requirements for Laravel:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PHP &amp;gt;= 5.6.4&lt;/li&gt;
  &lt;li&gt;OpenSSL PHP Extension&lt;/li&gt;
  &lt;li&gt;PDO PHP Extension&lt;/li&gt;
  &lt;li&gt;Mbstring PHP Extension&lt;/li&gt;
  &lt;li&gt;Tokenizer PHP Extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These notes describe installing Laravel on PHP 7 with MariaDB and Apache.&lt;/p&gt;

&lt;h2 id=&quot;laravel-installer&quot;&gt;Laravel Installer&lt;/h2&gt;
&lt;p&gt;Use Composer to download the Laravel installer. It will then be available globally:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;composer global require &lt;span class=&quot;s2&quot;&gt;&quot;laravel/installer&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will place the installer in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.composer/vendor/laravel/installer/&lt;/code&gt;, symlinked in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.composer/vendor/bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This latter directory shoudl be in your &lt;code class=&quot;highlighter-rouge&quot;&gt;$PATH&lt;/code&gt; so that the &lt;code class=&quot;highlighter-rouge&quot;&gt;laravel&lt;/code&gt; installer can be located by the system. You may need to add the follwoing to your &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt; file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Add to ~/.bashrc for global access to Laravel installer&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.composer/vendor/bin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The Laravel installer calls the &lt;code class=&quot;highlighter-rouge&quot;&gt;Symfony\Component\Console\Application&lt;/code&gt; class to work it’s magic.&lt;/p&gt;

&lt;h2 id=&quot;installing-laravel&quot;&gt;Installing Laravel&lt;/h2&gt;
&lt;p&gt;The development site will be located in the Apache docroot - and the installer will install Laravel in the &lt;strong&gt;current directory&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/html
laravel new project-name&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Accessing &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/project-name/&lt;/code&gt; in a browser will display the app directory structure.&lt;/p&gt;

&lt;h2 id=&quot;post-installation-permissions&quot;&gt;Post-Installation Permissions&lt;/h2&gt;
&lt;p&gt;Assuming the Apache user is &lt;code class=&quot;highlighter-rouge&quot;&gt;www-data&lt;/code&gt;, the following ownership settings need to be applied:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Move into the new project root&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/html/project-name

&lt;span class=&quot;c&quot;&gt;# Apply ownership&lt;/span&gt;
sudo chown -R www-data storage
sudo chown -R www-data bootstrap/cache&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;the-public-directory&quot;&gt;The Public Directory&lt;/h2&gt;
&lt;p&gt;The front controller for Laravel is &lt;code class=&quot;highlighter-rouge&quot;&gt;public/index.php&lt;/code&gt; file - this is the file that all requests hit. The &lt;code class=&quot;highlighter-rouge&quot;&gt;public&lt;/code&gt; directory will be the document root for the project.&lt;/p&gt;

&lt;p&gt;If you’ve set permissions correctly, you should be able to access the new app:
&lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/project-name/public/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It’s abit cumbersome to use this URL in the development environment. You should instead configure a virtual host directive for a suitable URL, and adjust your &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; file so that your chosen domain directs to 127.0.0.1 (localhost).&lt;/p&gt;

&lt;h2 id=&quot;localhost-and-the-trailing-slash&quot;&gt;Localhost and the Trailing Slash&lt;/h2&gt;
&lt;p&gt;There is a “gotcha” if you decide to devlop locally under Apache localhost - adding a trailing slash to the URL &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/your-app/page/&lt;/code&gt; triggers Laravel to redirect to a non-trailing slashed home URL, which will be &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/page&lt;/code&gt; rather than &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/your-app/page&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This can be worked around (maybe by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; rules) - but it’s probably easier all round to just set up a local Apache virtual host config and amend &lt;code class=&quot;highlighter-rouge&quot;&gt;etc/hosts&lt;/code&gt; to point to your localhost for a specified domain.&lt;/p&gt;

&lt;h2 id=&quot;post-install-checks&quot;&gt;Post Install Checks&lt;/h2&gt;
&lt;p&gt;Check the 32 character application key in &lt;code class=&quot;highlighter-rouge&quot;&gt;.env&lt;/code&gt; has been set to a random string.&lt;/p&gt;
</description>
        <pubDate>Sat, 27 Aug 2016 17:48:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/install-laravel-on-ubuntu-16-04-desktop/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/install-laravel-on-ubuntu-16-04-desktop/</guid>
      </item>
      
    
      
      <item>
        <title>Moving a Site to a New Domain - Apache Redirects/Rewrites</title>
        <description>&lt;p&gt;When moving a site to a new domain, it’s important to redirect visitors to the new domain. This provides a courtesy to your users, helps retain search engine ranking, and prevents broken links to your site.&lt;/p&gt;

&lt;p&gt;Apache provides several methods for redirecting requests and this article documents several approaches.&lt;/p&gt;

&lt;p&gt;The rules should be tested properly before applying them. In our case, we set up a virtual machine with cloned versions of both new and old sites (with an appropriately modified hosts file) to allow full testing of all redirects.&lt;/p&gt;

&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;This article refers to a site that is being moved to a new domain as part of a re-branding exercise.&lt;/p&gt;

&lt;p&gt;The site structure will remain broadly the same, but for two quite important differences. The old site permalink structure for the ‘projects’ and ‘people’ index pages is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;http://olddomain/category/people/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;http://olddomain/category/projects/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the new site, these index pages will be located at the following URLs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;http://newdomain/people/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;http://newdomain/projects/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, project categories (a custom taxonomy) are to be rationalised as part of the move/rebuild. The old URL structure involved having ‘projects’ as a category, with projects further grouped into sub-categories. For the new site, these sub-categories have been mapped into a more logical ‘project-category’ structure.&lt;/p&gt;

&lt;p&gt;The resource found on the old domain at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://olddomain/category/projects/term/&lt;/code&gt; should be available at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://newdomain/project-category/term/&lt;/code&gt; on the new domain.&lt;/p&gt;

&lt;h2 id=&quot;approach&quot;&gt;Approach&lt;/h2&gt;
&lt;p&gt;The redirects can be achieved with a combination of Redirect and Rewrite rules, or Rewrite rules only. Rules can be added on a Directory basis (either &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; or in a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt; block in the vHost config).&lt;/p&gt;

&lt;p&gt;A better approach would probably be to include all necessary rewrite rules outside a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt; block within the vHost configuration. This allows the redirect to happen without even the presence of a directory corresponding to the old domain - so when the move is complete, the old site can be collapsed completely.&lt;/p&gt;

&lt;h2 id=&quot;per-directory-rules-htaccess&quot;&gt;Per-Directory Rules: &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;These rules are added to a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file in the root directory of the old site.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Redirect&lt;/span&gt; 301 /category/people/ http://newdomain.com/people/
&lt;span class=&quot;nc&quot;&gt;Redirect&lt;/span&gt; 301 /category/projects/ http://newdomain.com/projects/

&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{HTTP_HOST} !newdomain.com$ [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_URI} !^/category/people/$ [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_URI} !^/category/projects/$ [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(category/projects/)(.*)$ http://newdomain.com/project-category/$2
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(.*)$ http://newdomain.com/$1 [L,R=301]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Alternatively, the rewrite engine only could be used:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
&lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;FollowSymLinks&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{HTTP_HOST} !newdomain.com$ [NC]
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(category/people/)$ http://newdomain.com/people/ [L,R=301]
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(category/projects/)$ http://newdomain.com/projects/ [L,R=301]
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(category/projects/)(.*)$ http://newdomain.com/project-category/$2 [L,R=301]
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(.*)$ http://newdomain.com/$1 [L,R=301]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the first string to be matched should not have a leading slash. This is because in the directory context (within either a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt; block or a per-directory &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file) the removed prefix always ends with a slash - so a Pattern with &lt;code class=&quot;highlighter-rouge&quot;&gt;^/&lt;/code&gt; never matches in the per-directory context.&lt;/p&gt;

&lt;p&gt;Bracketed sections of the source string are available as indexed variables in the destination string:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Rewrite http://olddomain.com/first-string/second-string/...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ...to http://newdomain/second-string:&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(first-string/)(second-string)$ http://newdomain/$2`&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; for testing purposes, you should designate these rules as “302” - a temporary redirect. These should be amended to “301” to denote a permanent redirect when you deploy the rules to the production server.&lt;/p&gt;

&lt;p&gt;These rules could be placed in either a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file in the olddomain.com document root or a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt; block in the site virtual host configuration file for the old site (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/sites-available/olddomain.com.conf&lt;/code&gt;). If adding the rules to an Apache config file, you’ll need to restart Apache for the rules to take effect.&lt;/p&gt;

&lt;h2 id=&quot;simple-vhost-redirect&quot;&gt;Simple vHost Redirect&lt;/h2&gt;
&lt;p&gt;This block added to the virtual host configuration of the &lt;strong&gt;old&lt;/strong&gt; site provides a one-to-one mapping of the old domain to the new. If the site retains the exact same permalinks (apart from the domain of course), this might be an adequate solution. Note that a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Directory&amp;gt;&lt;/code&gt; block is not necessary:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; oldsite.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.oldsite.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@olddomain.com

        &lt;span class=&quot;nc&quot;&gt;Redirect&lt;/span&gt; 301 / http://newdomain.com

        &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/oldsite.com.error.log
        &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/oldsite.com.access.log combined
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This kind of simple redirect isn’t going to work in our case, because the structure of some of our URLs will be altered.&lt;/p&gt;

&lt;h2 id=&quot;complete-vhost-redirect&quot;&gt;Complete vHost Redirect&lt;/h2&gt;
&lt;p&gt;Here’s the final virtual host config file solution:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; olddomain.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.olddomain.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@olddomain.com
        &lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; On
        &lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{HTTP_HOST} !newdomain.com$ [NC]
        &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(/category/people/)$ http://newdomain.com/people/ [L,R=301]
        &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(/category/projects/)$ http://newdomain.com/projects/ [L,R=301]
        &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(/category/projects/)(.*)$ http://newdomain.com/project-category/$2 [L,R=301]
        &lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(.*)$ http://newdomain.com/$1 [L,R=301]
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Don’t forget to restart Apache for the rewrite rules to take effect.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule&quot;&gt;Apache 2.4 docs on mod_rewrite&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/websites/apache-tips-and-tricks/redirect-urls-with-the-apache-web-server/&quot;&gt;Linode Guide on redirects&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.inmotionhosting.com/support/website/redirects/setting-up-a-301-permanent-redirect-via-htaccess&quot;&gt;Setting up 301 redirects via .htaccess&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://tltech.com/info/rewriterule-in-htaccess-vs-httpd-conf/&quot;&gt;.htaccess and Directory block level Rewrite Rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 26 Aug 2016 15:45:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/moving-a-site-to-a-new-domain/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/moving-a-site-to-a-new-domain/</guid>
      </item>
      
    
      
      <item>
        <title>Page Sections in Jekyll - Seperating Content from Layout</title>
        <description>&lt;p&gt;It’s usually considered good practice to keep content separate from logic and layout. I think this is especially important with static site generators like Jekyll, where it’s easy to mix content and layout.&lt;/p&gt;

&lt;p&gt;Achieving separation is pretty straightforward with single page/post/collection views - just define a custom template and inject the content from a markdown file (from yaml frontmatter and the main content field).&lt;/p&gt;

&lt;p&gt;But what about displaying section content in a single page context? This is a common requirement for landing pages, home pages and single page sites.&lt;/p&gt;

&lt;p&gt;Ideally, all content - including text, background image, foreground image etc should be controlled in the content markdown file. I’d go a step further and suggest that some style elements should also be controllable here - for example, if you add a background image which results in poor text/background contrast, you should be able to set the image overlay opacity in the same location that you’re setting the image.&lt;/p&gt;

&lt;h2 id=&quot;define-collections&quot;&gt;Define Collections&lt;/h2&gt;
&lt;p&gt;Jekyll collections are an ideal candidate for managing repeating content that is not naturally date ordered.&lt;/p&gt;

&lt;p&gt;Our use case here is for a very simple site, and our section content will be grouped using a jekyll collection that we’ll call “sections”.&lt;/p&gt;

&lt;p&gt;To begin, define the site collections in &lt;code class=&quot;highlighter-rouge&quot;&gt;_config.yml&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;s&quot;&gt;collections&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;sections&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then create a directory called &lt;code class=&quot;highlighter-rouge&quot;&gt;_sections&lt;/code&gt; in the project root. This directory will contain section files, stored in markdown format.&lt;/p&gt;

&lt;h2 id=&quot;the-index-page&quot;&gt;The Index Page&lt;/h2&gt;

&lt;p&gt;Iterating through the sections in &lt;code class=&quot;highlighter-rouge&quot;&gt;index.html&lt;/code&gt; looks like this:&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;&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;assign&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sections&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sections&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;sort&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;'order'&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;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;section&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;in&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;sections&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;section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;null&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;nt&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;{{&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;include }} %}
  {% else %}
    {% include sections/default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;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;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;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;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This does the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Assign a ‘sections’ object, by iterating through site sections (i.e. the &lt;code class=&quot;highlighter-rouge&quot;&gt;_sections/*.md&lt;/code&gt; files) and ordering by the “order” attribute (which is set in the section front matter)&lt;/li&gt;
  &lt;li&gt;Loop through these objects - for each one, if there is a specified include (again, set in the section frontmatter) then call it&lt;/li&gt;
  &lt;li&gt;If no include is specified in the section, call a default include as a fallback&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;the-includes&quot;&gt;The Includes&lt;/h2&gt;

&lt;p&gt;In our case we store includes under &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes/sections&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The includes are &lt;code class=&quot;highlighter-rouge&quot;&gt;html&lt;/code&gt; files that have the section content injected. This include shows how:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Inline style is included as defined by the section yaml frontmatter&lt;/li&gt;
  &lt;li&gt;Section content is injected into the section layout&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{% capture bg-image-style %}
 style=&quot;background:{% if section.bg-opaque-overlay != nil %} linear-gradient(
    {{ section.bg-opaque-overlay }},
    {{ section.bg-opaque-overlay }}
  ),{% endif %} {% if section.bg_image != nil %}url('{{ section.bg_image }}') center center fixed; background-size: cover;{% endif %}&quot;
{% endcapture %}
&lt;span class=&quot;nt&quot;&gt;&amp;lt;section&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ section.title | slugify }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;content-section&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bg-image-style&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-md-12&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ section.title }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      {{ section.content }}
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case the style rule builds in a background image with an opaque overlay.&lt;/p&gt;

&lt;p&gt;Obviously you can define as many layout includes as your project needs.&lt;/p&gt;

&lt;h2 id=&quot;the-content&quot;&gt;The Content&lt;/h2&gt;
&lt;p&gt;Content is held as a collection markdown file stored in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/_sections&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;For example, this is &lt;code class=&quot;highlighter-rouge&quot;&gt;_sections/about.md&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;About&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;path/to/img&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Set the display order for this section&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Specify the layout for this section&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;sections/two-column.html&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Set style variables&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;bg-opaque-overlay&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rgba(0,200,0,0.3)&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;bg_image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://loremflickr.com/2000/600/robot&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

&lt;span class=&quot;gu&quot;&gt;### Ut enim ad minim veniam&lt;/span&gt;

quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I like this method because content editing on the site is very simple, and site editors can have quite a few options available in the content markdown file. It also breaks apart the layout/HTML which I think makes projects more maintainable.&lt;/p&gt;

&lt;p&gt;There are probably better ways of organising section content - if you know of any, please leave a comment!&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://jekyllrb.com/docs/collections/&quot;&gt;Jekyll docs on Collections&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ben.balter.com/2015/02/20/jekyll-collections/&quot;&gt;Ben Balter on Jekyll Collections&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyll.tips/jekyll-casts/introduction-to-collections/&quot;&gt;Jekyll Casts on Jekyll Collections&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 10 Aug 2016 19:23:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/page-sections-in-jekyll-seperating-content-from-layout/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/page-sections-in-jekyll-seperating-content-from-layout/</guid>
      </item>
      
    
      
      <item>
        <title>Secure rsync Between Servers</title>
        <description>&lt;p&gt;This method allows for automatic incremental backups between servers.&lt;/p&gt;

&lt;h2 id=&quot;backup-server-pulls-from-production-server&quot;&gt;Backup Server Pulls from Production Server&lt;/h2&gt;
&lt;p&gt;Either server could initiate the sync - but if Production initiates, it would need write access to the Backup server. It is probably safest to give the Backup server read access to the Production server, so this guide assumes that the Backup machine initiates the sync.&lt;/p&gt;

&lt;p&gt;The files to be synced have been built by a local automatic rsync-based incremental backup script that runs on the Production server. This is because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There is enough space on the Production machine (approx 8G out of 40G is in use)&lt;/li&gt;
  &lt;li&gt;Having an incremental backup on the Production server allows for quick restores in the event of non-catastrophic failure&lt;/li&gt;
  &lt;li&gt;Having backups on the production server is “belt and braces” - backups are stored in multiple locations&lt;/li&gt;
  &lt;li&gt;The script has root access and can build a complete set of backup files: /var/www/html/, Apache config files, MySQL config files, Database files (built by mysqldump)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;rrsync&lt;/code&gt; perl script (restricted rsync) to restrict rsync to a subdirectory declared in .ssh/authorized_keys. This works really well since our local incremental backup has written all the files we need to a single backup directory.&lt;/p&gt;

&lt;p&gt;The Incremental Backup that is being synced is &lt;a href=&quot;/2015/06/incremental-backup-on-server/&quot;&gt;described here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-backup-user-on-the-production-server&quot;&gt;Set up a Backup User on the Production Server&lt;/h2&gt;
&lt;p&gt;Set up a user without sudo privileges. This user is only going to be used to store backups - which provides another level of security.&lt;/p&gt;

&lt;p&gt;The backup user home directory will receive incremental backups, and hold the SSH public key to allow the remote backup server to connect - and that’s about it.&lt;/p&gt;

&lt;h2 id=&quot;set-up-an-ssh-key-pair-on-the-backup-server&quot;&gt;Set up an SSH Key Pair on the Backup Server&lt;/h2&gt;
&lt;p&gt;Because the backup script is designed to be triggered automatically by a cron job, the user that will be running the rsync command on the production server will be root.&lt;/p&gt;

&lt;p&gt;It is therefore important to transfer the public SSH key for &lt;strong&gt;the root user&lt;/strong&gt; to the backup target machine.&lt;/p&gt;

&lt;p&gt;In addition, the SSH key should NOT have a passphrase, so that connection can be made automatically. We will also limit the actions that can be carried out by this SSH connection.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Switch to root&lt;/span&gt;
su root

&lt;span class=&quot;c&quot;&gt;# Generate an SSH key pair, WITHOUT a passphrase&lt;/span&gt;
ssh-keygen -t rsa

&lt;span class=&quot;c&quot;&gt;# copy the public key to the backupuser account on the target Production machine&lt;/span&gt;
ssh-copy-id -p 1234 backupuser@123.456.789.0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;failure-to-copy-public-key&quot;&gt;Failure to Copy Public Key&lt;/h2&gt;
&lt;p&gt;If the public key doesn’t copy across, you’ll see an error message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/usr/bin/ssh-copy-id: INFO: attempting to log &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;with the new key&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; remain to be installed -- &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;you are prompted now it is to install the new keys
Permission denied &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;publickey&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This means that the remote server has refused the connection.&lt;/p&gt;

&lt;p&gt;In my case, this is because I usually set up servers such that access is via SSH key only - with password authentication disabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To copy a public SSH key to a remote server, password SSH login must be enabled on the remote server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To enable password login:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SSH into the remote server&lt;/li&gt;
  &lt;li&gt;Configure SSH: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Edit to allow password authentication: &lt;code class=&quot;highlighter-rouge&quot;&gt;PasswordAuthentication yes&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Save &amp;amp; exit, then reload the SSH server: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo reload ssh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the key has been copied across (which will require password entry for the relevant user), test SSH access (as prompted). If it works, you can safely disable password login on the remote machine.&lt;/p&gt;

&lt;h2 id=&quot;limit-actions-for-this-ssh-connection-to-restricted-rsync&quot;&gt;Limit Actions for this SSH Connection to Restricted rsync&lt;/h2&gt;
&lt;p&gt;Using an SSH key without a passphrase makes it possible to automate remote tasks - a user-entered passphrase is not required for key decryption.&lt;/p&gt;

&lt;p&gt;Automation of backup tasks is essential - if backup relies on human intervention, sooner or later it will get missed or messed up. However, using SSH keys without a passphrase is a security risk - is someone had access to the backup server, they would be easily able to access the remote Production server.&lt;/p&gt;

&lt;p&gt;To prevent this, SSH allows restriction of the commands that can be executed by a specific set of keys. This is accomplished by editing the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/.ssh/authorized_keys&lt;/code&gt; file for the backup user on the Production server.&lt;/p&gt;

&lt;p&gt;A script called rrsync (which stands for restricted rsync) is provided with rsync specifically to ease the restricting keys to be used only for rsync via .ssh/authorized_keys.&lt;/p&gt;

&lt;p&gt;On Ubuntu, the script is located here: &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/doc/rsync/scripts/rrsync.gz&lt;/code&gt;. The script needs to be unzipped and installed under &lt;code class=&quot;highlighter-rouge&quot;&gt;user/local/bin&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Copy the archive rrsync script to /usr/local/bin&lt;/span&gt;
sudo cp /usr/share/doc/rsync/scripts/rrsync.gz  /usr/local/bin/

&lt;span class=&quot;c&quot;&gt;# Unzip the script&lt;/span&gt;
sudo gzip -d   /usr/local/bin/rrsync.gz

&lt;span class=&quot;c&quot;&gt;# Give it correct permissions&lt;/span&gt;
sudo chmod 755 /usr/local/bin/rrsync&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once &lt;code class=&quot;highlighter-rouge&quot;&gt;rrsync&lt;/code&gt; is in place, we can lock down access for our SSH key by amending the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Open the public key for the backup user on the Production Server. This will constitute a single line of text:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /home/backupuser/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Prepend the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin/rrsync -ro /home/path-to/backup/&quot;&lt;/span&gt;,no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;command=&quot;/usr/local/bin/rrsync ...&quot;&lt;/code&gt; restricts access of that particular public key - only the given command can be executed&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;...-ro /home/path-to/backup/&quot;&lt;/code&gt; gives &lt;strong&gt;read-only&lt;/strong&gt; access to the specified directory&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;no-*&lt;/code&gt; options further restrict what actions can be carried out with the public key.&lt;/li&gt;
  &lt;li&gt;Note that the full path is need to reference rrsync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try and SSH into the Production machine from the Backup server you should now see a message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PTY allocation request failed on channel 0
/usr/local/bin/rrsync: Not invoked via sshd
Use &lt;span class=&quot;s1&quot;&gt;'command=&quot;/usr/local/bin/rrsync [-ro] SUBDIR&quot;'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;front of lines &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /home/backupuser/.ssh/authorized_keys
Connection to 123.45.67.89 closed.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;command-rsync-from--backup-server&quot;&gt;Command rsync from  Backup Server&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; After the above amendment to the &lt;code class=&quot;highlighter-rouge&quot;&gt;authorized_keys&lt;/code&gt; file, the final path from the Backup servers point of view is now “/”:&lt;/p&gt;

&lt;p&gt;Sample rsync command from the Backup server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rsync --log-file&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.rsyncd.log --progress -az -H -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 1234&quot;&lt;/span&gt; backupuser@123.456.789.0:/ ~/backup-target-directory&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This specifies:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-a: archive mode; equals -rlptgoD (no -H,-A,-X)&lt;/li&gt;
  &lt;li&gt;-z: Compress file data during the transfer&lt;/li&gt;
  &lt;li&gt;-H: Maintain hardlinks (important due to our incremental backup)&lt;/li&gt;
  &lt;li&gt;-e “ssh -p 1234”: connect via SSH on port 1234&lt;/li&gt;
  &lt;li&gt;See &lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync man&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a more comprehensive script that sends an email with success/fail messages. This could be added to a nightly cronjob. It would be better if it looped through the servers:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Collect all of the backups!&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Server 1 Backup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rsync -aqz -H -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 22222&quot;&lt;/span&gt; backupuser@111.111.111.111:/ /home/david/server-1 2&amp;gt; /home/david/server-1-rsync.err

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -gt 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Server 1 errors&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# ----------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;SERVER_1_MSG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false
    echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;There was an error in the nightly backup for Server 1 to the backup server: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup Error, Server 1 to Backup&quot;&lt;/span&gt; info@example.com

  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Server 1 success&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# --------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;SERVER_1_MSG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rsync was successful for Server 1&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Server 2 Backup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rsync -aqz -H -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 22222&quot;&lt;/span&gt; backupuser@222.222.222.222:/ /home/david/server-2 2&amp;gt; /home/david/server-2-rsync.err

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -gt 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Server 2 errors&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# ----------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;SERVER_2_MSG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false
    echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;There was an error in the nightly backup for Server 2 to the backup server: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup Error, Server 2 to Backup&quot;&lt;/span&gt; info@example.com

  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Server 2 success&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# --------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;SERVER_2_MSG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rsync was successful for Server 2&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fi


&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;REPORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Backup Report, &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
===========================================
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVER_1_MSG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVER_2_MSG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$REPORT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup Status&quot;&lt;/span&gt; info@example.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;problems-with-permissions&quot;&gt;Problems with Permissions&lt;/h2&gt;
&lt;p&gt;Some files that you’re backing up may have restrictive permissions. For example, permissions on WordPress configuration file (&lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;) may be set to 660 - read/write for owner, read/write for group, and no privilege for others. Most files will have permission set to 644.&lt;/p&gt;

&lt;p&gt;Because your backup server is logging in as the backup user on the production server, it won’t have read privilege on the files with 660 permission. Trying to rsync these will result in a permission error.&lt;/p&gt;

&lt;p&gt;To prevent this, add the &lt;strong&gt;production server’s&lt;/strong&gt; backup user to the file’s group - typically &lt;code class=&quot;highlighter-rouge&quot;&gt;www-data&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Production server: server that is being backed up&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Add backup user to the group&lt;/span&gt;
usermod -a -G www-data backupuser&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will allow the backup server to log in as the backup user and copy files.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.guyrutenberg.com/2014/01/14/restricting-ssh-access-to-rsync/&quot;&gt;http://www.guyrutenberg.com/2014/01/14/restricting-ssh-access-to-rsync/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.debian-administration.org/users/lee/weblog/40&quot;&gt;https://www.debian-administration.org/users/lee/weblog/40&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://positon.org/rsync-command-restriction-over-ssh&quot;&gt;http://positon.org/rsync-command-restriction-over-ssh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surniaulula.com/2014/02/21/force-rsync-command-via-ssh-but-allow-any-directory/&quot;&gt;http://surniaulula.com/2014/02/21/force-rsync-command-via-ssh-but-allow-any-directory/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ramblings.narrabilis.com/using-rsync-with-ssh&quot;&gt;http://ramblings.narrabilis.com/using-rsync-with-ssh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 10 Aug 2016 12:40:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/secure-rsync-between-servers/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/secure-rsync-between-servers/</guid>
      </item>
      
    
      
      <item>
        <title>Export MySQL Users</title>
        <description>&lt;p&gt;Build a SQL command that can be used to reconstruct MySQL users - useful for migrating servers, or building a verification check server for backups.&lt;/p&gt;

&lt;p&gt;Run this command on the source server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace PASS with your root password for MySQL&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MYSQL_CONN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-uroot -pPASS&quot;&lt;/span&gt;

mysql &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MYSQL_CONN&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; --skip-column-names -A -e &lt;span class=&quot;s2&quot;&gt;&quot;SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') AS query FROM mysql.user WHERE user NOT IN ('root','pma','phpmyadmin','debian-sys-maint')&quot;&lt;/span&gt; | mysql &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MYSQL_CONN&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; --skip-column-names -A | sed &lt;span class=&quot;s1&quot;&gt;'s/$/;/g'&lt;/span&gt; &amp;gt; ~/MySQLUserGrants.sql&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See: &lt;a href=&quot;http://serverfault.com/a/399875&quot;&gt;http://serverfault.com/a/399875&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;GRANT USAGE ON &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TO &lt;span class=&quot;s1&quot;&gt;'xyz_user'&lt;/span&gt;@&lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt; IDENTIFIED BY PASSWORD &lt;span class=&quot;s1&quot;&gt;'*rehoorufiuhrfourur8'&lt;/span&gt;;
GRANT ALL PRIVILEGES ON &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;xyz&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TO &lt;span class=&quot;s1&quot;&gt;'xyz_user'&lt;/span&gt;@&lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt;;
GRANT SELECT, RELOAD, REPLICATION CLIENT, SHOW VIEW, EVENT, TRIGGER ON &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TO &lt;span class=&quot;s1&quot;&gt;'backup_user'&lt;/span&gt;@&lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt; IDENTIFIED BY PASSWORD &lt;span class=&quot;s1&quot;&gt;'yguirfuiyrfurfygufr'&lt;/span&gt;;
GRANT USAGE ON &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TO &lt;span class=&quot;s1&quot;&gt;'abc_user'&lt;/span&gt;@&lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt; IDENTIFIED BY PASSWORD &lt;span class=&quot;s1&quot;&gt;'*yguguyrfeguirefgiuryfegu'&lt;/span&gt;;
GRANT ALL PRIVILEGES ON &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;abc&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;.&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; TO &lt;span class=&quot;s1&quot;&gt;'abc_user'&lt;/span&gt;@&lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt;;
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is a set of valid SQL commands that can be run on the destination server to create the necessary users. You can then import files, import databases, adjust &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; if necessary and the migrated sites should work.&lt;/p&gt;

&lt;h2 id=&quot;find-all-users-for-a-database&quot;&gt;Find All Users for a Database&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Log in as mysql root user&lt;/span&gt;
mysql -u root -p
SELECT USER FROM mysql.db WHERE &lt;span class=&quot;nv&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'DB_NAME'&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://serverfault.com/questions/8860/how-can-i-export-the-privileges-from-mysql-and-then-import-to-a-new-server&quot;&gt;Export privileges from mysql and then import to a new server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://serverfault.com/a/13050&quot;&gt;A nice alias&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://serverfault.com/a/307741&quot;&gt;Variation on the alias&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 07 Aug 2016 17:52:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/export-mysql-users/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/export-mysql-users/</guid>
      </item>
      
    
      
      <item>
        <title>Persistent Iptables Rules in Ubuntu 16.04 Xenial Xerus</title>
        <description>&lt;p&gt;The process of persisting firewall rules in Ubuntu 16.04 is different to the procedure for 14.04.&lt;/p&gt;

&lt;p&gt;The Firewall setup is broadly the same as for 14.04 as &lt;a href=&quot;/2016/02/iptables-ubuntu-firewall/&quot;&gt;described here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article briefly describes how to import a set of rules for IPtables and make these rules persist across reboots.&lt;/p&gt;

&lt;h2 id=&quot;export-rules&quot;&gt;Export Rules&lt;/h2&gt;
&lt;p&gt;If you’re exporting a ruleset from an existing Ubuntu 14.04 server, log in to this machine. Assuming that the &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables-persistent&lt;/code&gt; package is installed, run the following commands:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo iptables-save &amp;gt; ~/iptables-rules/ruleset-v4
sudo ip6tables-save &amp;gt; ~/iptables-rules/ruleset-v6&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Copy these ruleset files across to a temporary location on your Ubuntu 16.04 server.&lt;/p&gt;

&lt;h2 id=&quot;install-iptables-persistent&quot;&gt;Install iptables-persistent&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Install package&lt;/span&gt;
sudo apt-get install iptables-persistent

&lt;span class=&quot;c&quot;&gt;# Start - Thanks to Dave Wood for the correction in the comments section&lt;/span&gt;
sudo service netfilter-persistent start

&lt;span class=&quot;c&quot;&gt;#Add to startup&lt;/span&gt;
sudo invoke-rc.d netfilter-persistent save

&lt;span class=&quot;c&quot;&gt;# Stop the service&lt;/span&gt;
sudo service netfilter-persistent stop&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;import-rules&quot;&gt;Import Rules&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Import Rules&lt;/span&gt;
sudo iptables-restore &amp;lt; ~/serenity-iptables-rules/ruleset-v4
sudo ip6tables-restore &amp;lt; ~/serenity-iptables-rules/ruleset-v6

&lt;span class=&quot;c&quot;&gt;# Check iptables&lt;/span&gt;
sudo iptables -S&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;save-rules&quot;&gt;Save Rules&lt;/h2&gt;
&lt;p&gt;To save the imported rules, run the iptables-persistent dpkg-reconfigure script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo dpkg-reconfigure iptables-persistent&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The commands &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo netfilter-persistent save&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo netfilter-persistent reload&lt;/code&gt; should work, but we’ve had problems with these commands and resorted to the dpkg-reconfigure option. It may be that a restart of the service is necessary after running these commands.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;dpkg-reconfigure&lt;/code&gt; causes &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables-persistent&lt;/code&gt; to repeat the install procedure - it will prompt for you to save the current rules. The current iptables rules will be saved into a file by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables-save &amp;gt;/etc/iptables/rules.v4&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;ip6tables-save &amp;gt;/etc/iptables/rules.v6&lt;/code&gt;. You should see your rules in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/iptables/rules.v4&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/iptables/rules.v6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables-persistent&lt;/code&gt; package causes the following to run on reboot:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables-restore &amp;lt; /etc/iptables/rules.v4
ip6tables-restore &amp;lt; /etc/iptables/rules.v6&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;persistent-rules-and-fail2ban&quot;&gt;Persistent Rules and Fail2Ban&lt;/h2&gt;
&lt;p&gt;If you save iptables rules for restoration on reboot, and they contain rules added by Fail2Ban, Fail2Ban will duplicate the rules on boot. After a few reboots, the iptables can potentially get very messy.&lt;/p&gt;

&lt;p&gt;To avoid this, stop the fail2ban service before saving the reconfiguration, and manually edit the saved rules to remove references to Fail2Ban. Rebooting should result in the correct rules being added, as Fail2Ban adds it’s own:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Stop Fail2Ban&lt;/span&gt;
sudo fail2ban-client stop

&lt;span class=&quot;c&quot;&gt;# Configure Persistent Rules&lt;/span&gt;
sudo dpkg-reconfigure iptables-persistent

&lt;span class=&quot;c&quot;&gt;# Make a backup copy (repeat for the v6 ruleset)&lt;/span&gt;
sudo cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.bak

&lt;span class=&quot;c&quot;&gt;# Edit, remove references to Fail2Ban:&lt;/span&gt;
sudo nano /etc/iptables/rules.v4

&lt;span class=&quot;c&quot;&gt;# Reboot to apply proper rules &amp;amp; restart Fail2Ban&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# (probably better to reload rules and restart Fail2Ban - these are rough notes)&lt;/span&gt;
sudo reboot&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/a/373526/463571&quot;&gt;http://askubuntu.com/a/373526/463571&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/a/30819095/3590673&quot;&gt;http://stackoverflow.com/a/30819095/3590673&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kromey.us/2016/07/setting-up-an-iptables-firewall-part-3-777.html&quot;&gt;https://kromey.us/2016/07/setting-up-an-iptables-firewall-part-3-777.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://oitibs.com/easy-ubuntu-16-server-firewall/&quot;&gt;https://oitibs.com/easy-ubuntu-16-server-firewall/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 07 Aug 2016 15:35:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/persistent-iptables-rules-in-ubuntu-16-04-xenial-xerus/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/persistent-iptables-rules-in-ubuntu-16-04-xenial-xerus/</guid>
      </item>
      
    
      
      <item>
        <title>Apache Virtual Host Setup</title>
        <description>&lt;p&gt;Apache Virtual Hosts allows multiple sites to be hosted on a single server/VPS.&lt;/p&gt;

&lt;p&gt;These guidelines are for configuration of virtual hosts on Apache 2.4.&lt;/p&gt;

&lt;h2 id=&quot;create-directory-structure&quot;&gt;Create Directory Structure&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p /var/www/html/example.com/public_html
sudo mkdir -p /var/www/html/example2.com/public_html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The -p flag creates intermediate directories as required.&lt;/p&gt;

&lt;p&gt;Give permissions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /var/www/example.com/public_html
sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /var/www/test.com/public_html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; WordPress is going to need the www-data to have ownership of the public_html subdirectories to allow file upload etc. - for the time being, give ownership to the current user - pass ownership to www-data later.&lt;/p&gt;

&lt;p&gt;Set Permissions to 755 for directories:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chmod -R 755 /var/www&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add index.html demo pages if necessary.&lt;/p&gt;

&lt;h2 id=&quot;create-config-files&quot;&gt;Create Config Files&lt;/h2&gt;
&lt;p&gt;Create a config file for each site:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/yoursite.com.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Use this as a template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@example.com
        &lt;span class=&quot;nc&quot;&gt;DocumentRoot&lt;/span&gt; /var/www/html/example.com/public_html
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/html/example.com/public_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;                &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Indexes +FollowSymLinks
                &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;All&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all granted
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.error.log
        &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/example.com.access.log combined
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This config block sets the correct server name, alias and document root. Directory browsing is disallowed, and .htaccess files are allowed.&lt;/p&gt;

&lt;p&gt;Site specific error reporting is added - log files are located here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/var/log/apache2/yoursite.com.error.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Enable the site using &lt;code class=&quot;highlighter-rouge&quot;&gt;a2ensite&lt;/code&gt;and restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2ensite yoursite.com.conf
sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;enable-apache-rewrites&quot;&gt;Enable Apache Rewrites&lt;/h2&gt;
&lt;p&gt;Enabling the Apache rewrite module will be essential it you’re using pretty permalinks. Enable the module &amp;amp; restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod rewrite &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod rewrite &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo /etc/init.d/apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up--permanent-redirect&quot;&gt;Set Up  Permanent Redirect&lt;/h2&gt;

&lt;p&gt;Configure a new Virtual Host on the server to intercept requests for the old domain, and permanently redirect them to the new domain:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;nc&quot;&gt;ServerName&lt;/span&gt; olddomain-example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAlias&lt;/span&gt; www.olddomain-example.com
        &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; info@example.com

        &lt;span class=&quot;nc&quot;&gt;Redirect&lt;/span&gt; 301 / http://new-example.com/

        &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/olddomain-example.com.error.log
        &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/olddomain-example.com.access.log combined
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Fri, 05 Aug 2016 11:29:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/08/apache-virtual-host-setup/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/08/apache-virtual-host-setup/</guid>
      </item>
      
    
      
      <item>
        <title>Bulk Import Images Using WP-CLI</title>
        <description>&lt;p&gt;Use &lt;a href=&quot;http://wp-cli.org/&quot;&gt;WP-CLI&lt;/a&gt; to bulk import images to the WordPress media library.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;wp media import&lt;/code&gt; command creates attachments from local files or URLs. The utility has the ability to recurse through subdirectories, making it very useful.&lt;/p&gt;

&lt;p&gt;A typical workflow might involve:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Getting the raw images&lt;/li&gt;
  &lt;li&gt;Bulk renaming image files (e.g. to include client details and an index number)&lt;/li&gt;
  &lt;li&gt;Bulk image processing using &lt;a href=&quot;https://github.com/DavidCWebs/bash-image-processor&quot;&gt;a custom script&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;wp media import&lt;/code&gt; to import images, either to a local dev site or a staging site&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;bulk-import&quot;&gt;Bulk Import&lt;/h2&gt;

&lt;p&gt;WP-CLI makes it easy to run a bulk import from the command line:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Import all images from a local directory, without attaching to posts&lt;/span&gt;
wp media import ~/Pictures/processed-images-medium/&lt;span class=&quot;se&quot;&gt;\*\*\/\*&lt;/span&gt;.jpg&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The command works recursively, but relies on the glob capabilities of the current shell.&lt;/p&gt;

&lt;p&gt;“Globbing” is what the shell does when it encounters a wildcard (like “*”) in a command. Bash 4.0 offers an option called &lt;code class=&quot;highlighter-rouge&quot;&gt;globstar&lt;/code&gt; which is used for “**”. As seen in the command above, the “**” pattern allows the command to recurse all directories.&lt;/p&gt;

&lt;p&gt;Under Ubuntu 16.04, the globstar option must be turned on for this to work. By default, it isn’t - and the command will not act recursively. To turn globstar on:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;shopt&lt;/span&gt; -s globstar
wp media import ~/Pictures/processed-images-medium/&lt;span class=&quot;se&quot;&gt;\*\*\/\*&lt;/span&gt;.jpg&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;attach-an-image-to-a-post&quot;&gt;Attach an Image to a Post&lt;/h2&gt;
&lt;p&gt;The WP-CLI &lt;code class=&quot;highlighter-rouge&quot;&gt;wp media import&lt;/code&gt; command can also be used to import images as featured images for specified posts:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp media import ~/Pictures/image.png --post_id&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;123 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
--title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A downloaded picture&quot;&lt;/span&gt; --featured_image
&lt;span class=&quot;c&quot;&gt;# See: http://wp-cli.org/commands/media/import/#examples&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;import-an-image-as-the-featured-image-for-all-posts&quot;&gt;Import an Image as the Featured Image for All posts&lt;/h2&gt;
&lt;p&gt;This is a pretty handy feature for setting up development sites:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Line 1&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;ATT_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;wp media import ~/Pictures/swimming.jpg --porcelain&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Line 2&lt;/span&gt;
wp post list --post_type&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;post --format&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ids | &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Line 3&lt;/span&gt;
xargs -0 -d &lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt; -I % wp post meta add % &lt;span class=&quot;se&quot;&gt;\_&lt;/span&gt;thumbnail_id &lt;span class=&quot;nv&quot;&gt;$ATT_ID&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Walkthrough:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;--porcelain&lt;/code&gt; option causes the new attachment ID to be output, so this line runs the import and sets the $ATT_ID shell variable to the imported image ID&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;wp post list --post_type=post --format=ids&lt;/code&gt; gets a list of post IDs in a space-separated string format and passes this to &lt;code class=&quot;highlighter-rouge&quot;&gt;xargs&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;xargs&lt;/code&gt; operates on each ID, setting the post meta &lt;code class=&quot;highlighter-rouge&quot;&gt;_thumbnail_id&lt;/code&gt; field for each post ID. The &lt;code class=&quot;highlighter-rouge&quot;&gt;xargs&lt;/code&gt; options set a space as the delimiter&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://wp-cli.org/commands/media/import/#examples&quot;&gt;WP-CLI wp media import command examples&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wp-cli.org/commands/post/list/&quot;&gt;WP-CLI wp post list&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 31 Jul 2016 17:10:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/07/bulk-import-images-using-wp-cli/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/07/bulk-import-images-using-wp-cli/</guid>
      </item>
      
    
      
      <item>
        <title>Add MixitUp to a Sage Project</title>
        <description>&lt;p&gt;MixItUp is a very useful jQuery filtering plugin.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;MixItUp is free to use in non-commercial projects under the terms of the creative commons CC-BY-NC license. However, for use in commercial projects and products we require that you purchase a commercial license.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://mixitup.kunkalabs.com/licenses&quot;&gt;mixitup.kunkalabs.com/licenses&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the time of writing, the single developer commercial license is $25.&lt;/p&gt;

&lt;h2 id=&quot;install-using-bower&quot;&gt;Install Using Bower&lt;/h2&gt;
&lt;p&gt;Run the following line in your project root - Mixitup will be downloaded as a &lt;code class=&quot;highlighter-rouge&quot;&gt;bower_component&lt;/code&gt;, and the project &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; will be amended:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bower install bower-mixitup --save&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The project &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; now looks like this, with a new dependency:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;your-projectname&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;homepage&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;http://carawebs.com/&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;authors&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;David Egan &amp;lt;david@carawebs.com&amp;gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;license&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;MIT&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;private&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;mixitup&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bower-mixitup#^2.0.4&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Sage 8 uses the &lt;a href=&quot;https://github.com/austinpray/asset-builder&quot;&gt;Asset Builder&lt;/a&gt; to pipeline assets. This results in an almost magical connecting up of resources, but it needs the imported project’s &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; to reference the “main” file for the package. The Mixitup &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; doesn’t do this, so an override must be added to the PROJECT &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt;, which now looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;your-projectname&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;homepage&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;http://carawebs.com/&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;authors&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;David Egan &amp;lt;david@carawebs.com&amp;gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;license&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;MIT&quot;&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;private&quot;&lt;/span&gt;: &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;mixitup&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;bower-mixitup#^2.0.4&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;overrides&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;mixitup&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./src/jquery.mixitup.js&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this example, the main file referenced is an un-minified version - which can make debugging easier. You may as well add the unminified version, since the Sage asset pipeline handles minification.&lt;/p&gt;

&lt;p&gt;Adding this allows Asset Builder to grab the imported file and build it into the asset pipeline - which lead us on to the next step.&lt;/p&gt;

&lt;h2 id=&quot;add-to-manifestjson&quot;&gt;Add to manifest.json&lt;/h2&gt;
&lt;p&gt;Adding a proper reference to the bower-installed project in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/assets/manifest.json&lt;/code&gt; file will result in a minified asset being built into the &lt;code class=&quot;highlighter-rouge&quot;&gt;dist&lt;/code&gt; directory when &lt;code class=&quot;highlighter-rouge&quot;&gt;gulp&lt;/code&gt; is run.&lt;/p&gt;

&lt;p&gt;Now the asset can be conditionally enqueued where it is needed (it could alternatively be built into &lt;code class=&quot;highlighter-rouge&quot;&gt;main.js&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;enqueuing&quot;&gt;Enqueuing&lt;/h2&gt;
&lt;p&gt;To stick with the Sage convention, add your enqueue to the &lt;code class=&quot;highlighter-rouge&quot;&gt;assets()&lt;/code&gt; function in &lt;code class=&quot;highlighter-rouge&quot;&gt;/lib/setup.php&lt;/code&gt;. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_post_type_archive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'project'&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;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;wp_enqueue_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'mixitup'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Assets\asset_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'scripts/mixitup.js'&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;s1&quot;&gt;'jquery'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;wp_enqueue_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'filter'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Assets\asset_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'scripts/filter.js'&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;s1&quot;&gt;'jquery'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;setting-up&quot;&gt;Setting Up&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Create HTML with the right container and filterable elements&lt;/li&gt;
  &lt;li&gt;Add/enqueue JavaScript to initiate and control mixitup&lt;/li&gt;
  &lt;li&gt;Create a HTML filter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; By default, MixitUp looks for elements with the class &lt;code class=&quot;highlighter-rouge&quot;&gt;.mix&lt;/code&gt; and designates these as filterable elements. You can override this, but if you don’t, and your filter elements don’t have the &lt;code class=&quot;highlighter-rouge&quot;&gt;.mix&lt;/code&gt; class, MixItUp isn’t going to work.&lt;/p&gt;
</description>
        <pubDate>Sat, 30 Jul 2016 09:53:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/07/add-mixitup-to-a-sage-project/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/07/add-mixitup-to-a-sage-project/</guid>
      </item>
      
    
      
      <item>
        <title>Delete files in Atom under Ubuntu 16.04</title>
        <description>&lt;p&gt;Atom is my editor of choice - I really enjoy working in it, to the point where I even write content and prepare client reports from within Atom (I can build in git logs, write in Markdown, and convert to PDF for the client). Going back to Tiny MCE in WordPress feels horrible! Atom is free, open source and very hackable - but I recently had a problem with file deletion.&lt;/p&gt;

&lt;h2 id=&quot;trashing-files&quot;&gt;Trashing Files&lt;/h2&gt;
&lt;p&gt;When trying to delete files in Atom 1.8.0 running on Ubuntu Xenial, you may experience a problem whereby file deletion is not possible. The error message returned by Atom suggests that &lt;code class=&quot;highlighter-rouge&quot;&gt;gvfs-trash&lt;/code&gt; is not installed:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The following file couldn’t be moved to trash (is gvfs-trash installed?)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;debugging-steps&quot;&gt;Debugging Steps&lt;/h2&gt;
&lt;p&gt;Check that gvfs-trash is working by opening a terminal &amp;amp; moving to a development directory - in this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;var/www/html/devsite&lt;/code&gt; - and attempting to delete a file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gvfs-trash filename

&lt;span class=&quot;c&quot;&gt;# this returns:&lt;/span&gt;
Error trashing file: Unable to find or create trash directory&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This gives a clue - it looks like:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Atom uses &lt;code class=&quot;highlighter-rouge&quot;&gt;gvfs-trash&lt;/code&gt; to send files to Trash on delete&lt;/li&gt;
  &lt;li&gt;When the file to be deleted is located outside the home directory, there is a problem - the &lt;code class=&quot;highlighter-rouge&quot;&gt;gvfs-trash&lt;/code&gt; process fails&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It would be good if Atom could return the &lt;code class=&quot;highlighter-rouge&quot;&gt;gvfs-trash&lt;/code&gt; error message, as this gives just enough information to hint towards a solution.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;Create a new Trash directory that can be accessed from outside the user’s home directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Create a Trash directory (with some subdirectories) in root&lt;/span&gt;
sudo mkdir -p /.Trash-1000/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;expunged,files,info&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Give ownership of this to your user:&lt;/span&gt;
sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /.Trash-1000&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That’s it - problem solved!&lt;/p&gt;

&lt;p&gt;The answer had been staring me in the face for weeks - some of my repos are in my home directory (mainly BASH scripts and system utilities) and files in these directories were deleting without issue. It didn’t dawn on me that the issue only cropped up in my Apache doc root (&lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/html/*&lt;/code&gt;). Facepalm.&lt;/p&gt;

&lt;p&gt;Posting this here to prevent repeating myself the next time I set up a development environment.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://manpages.ubuntu.com/manpages/trusty/man1/gvfs-trash.1.html&quot;&gt;gvfs-trash Ubuntu man page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/a/491953/463571&quot;&gt;Useful Askubuntu answer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;useful-gvfs-trash-commands&quot;&gt;Useful &lt;code class=&quot;highlighter-rouge&quot;&gt;gvfs-trash&lt;/code&gt; Commands&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Move oldfile to trash&lt;/span&gt;
gvfs-trash oldfile

&lt;span class=&quot;c&quot;&gt;# See contents of trash:&lt;/span&gt;
gvfs-ls trash://

&lt;span class=&quot;c&quot;&gt;# Take out the trash:&lt;/span&gt;
gvfs-trash --empty&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 26 Jul 2016 19:54:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/07/delete-files-in-atom-under-ubuntu-16-04/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/07/delete-files-in-atom-under-ubuntu-16-04/</guid>
      </item>
      
    
      
      <item>
        <title>Sync a Forked Git Repo to Upstream</title>
        <description>&lt;p&gt;When you have forked a repo, it can be useful to pull in changes that have been made to the original.&lt;/p&gt;

&lt;p&gt;Git makes this pretty straightforward.&lt;/p&gt;

&lt;h2 id=&quot;configure-git-remote&quot;&gt;Configure Git Remote&lt;/h2&gt;
&lt;p&gt;To list the current remotes in your project, cd into the repo directory and run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git remote -v

&lt;span class=&quot;c&quot;&gt;# Outputs:&lt;/span&gt;
origin  git@bitbucket.org:Username/project.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fetch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
origin  git@bitbucket.org:Username/project.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;push&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Configure a git remote that points to the upstream repo (the original that you forked from):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git remote add upstream git@bitbucket.org:vendor/original-project.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;sync-to-the-upstream-repo&quot;&gt;Sync to the Upstream Repo&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Fetch data from the upstream repo - commits to master will be stored in a local &lt;code class=&quot;highlighter-rouge&quot;&gt;upstream/master&lt;/code&gt; branch&lt;/li&gt;
  &lt;li&gt;Checkout the fork’s master branch (if you’re not already on master)&lt;/li&gt;
  &lt;li&gt;Merge changes from &lt;code class=&quot;highlighter-rouge&quot;&gt;upstream/master&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git fetch upstream

git checkout master

git merge upstream/master&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;automatic-synchronization&quot;&gt;Automatic Synchronization&lt;/h2&gt;
&lt;p&gt;Bitbucket allows &lt;a href=&quot;https://confluence.atlassian.com/bitbucketserver/keeping-forks-synchronized-776639961.html&quot;&gt;automatic fork synchronization&lt;/a&gt; - this is enabled in the Bitbucket GUI when you first fork the repo. I’ve not used this feature.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/syncing-a-fork/&quot;&gt;Syncing a Fork (GitHub)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://confluence.atlassian.com/bitbucketserver/keeping-forks-synchronized-776639961.html&quot;&gt;Keeping Forks Synchronized (Atlassian)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/configuring-a-remote-for-a-fork/&quot;&gt;Configuring a remote for a fork&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 03 Jul 2016 10:55:39 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/07/sync-a-forked-git-repo-to-upstream/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/07/sync-a-forked-git-repo-to-upstream/</guid>
      </item>
      
    
      
      <item>
        <title>Using git Branches</title>
        <description>&lt;p&gt;Git branches are a good way to work on a feature or a bugfix.&lt;/p&gt;

&lt;p&gt;You can create and switch to a new branch, which allows you to work without affecting the production code. Once happy wit changes, the branch can be merged back and deployed.&lt;/p&gt;

&lt;h2 id=&quot;determine--switch-branches&quot;&gt;Determine &amp;amp; Switch Branches&lt;/h2&gt;
&lt;p&gt;Enter &lt;code class=&quot;highlighter-rouge&quot;&gt;git branch&lt;/code&gt;. Returns branches, current branch indicated.&lt;/p&gt;

&lt;p&gt;To switch:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git checkout &amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-new-branch-local&quot;&gt;Create New Branch (Local)&lt;/h2&gt;
&lt;p&gt;To create and switch to a new branch:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git checkout -b &amp;lt;newbranchname&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Don’t forget to &lt;code class=&quot;highlighter-rouge&quot;&gt;git push origin &amp;lt;newbranchname&amp;gt;&lt;/code&gt; rather than pushing to master, which will return an “up to date” message.&lt;/p&gt;

&lt;p&gt;The remote repo will add the new branch when the local is pushed.&lt;/p&gt;

&lt;h2 id=&quot;see-which-files-have-changed&quot;&gt;See Which Files Have Changed&lt;/h2&gt;
&lt;p&gt;Check to see which files have changed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git diff --name-status master..&amp;lt;branchname&amp;gt;

&lt;span class=&quot;c&quot;&gt;# even more info:&lt;/span&gt;
git diff --stat --color master..&amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;merge-branch-into-master&quot;&gt;Merge Branch into Master&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Switch to master branch: &lt;code class=&quot;highlighter-rouge&quot;&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Merge: &lt;code class=&quot;highlighter-rouge&quot;&gt;git merge &amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the master has changed since the branch was created, this will result in a merge conflict.&lt;/p&gt;

&lt;h2 id=&quot;dealing-with-merge-conflicts&quot;&gt;Dealing With Merge Conflicts&lt;/h2&gt;
&lt;p&gt;Merge conflicts generally result when the same part of a file has been changed by different branches.&lt;/p&gt;

&lt;p&gt;During the merge, git will generate a useful merge-conflict message highlighting the file with the conflict. Running &lt;code class=&quot;highlighter-rouge&quot;&gt;git status&lt;/code&gt; will show information about the conflict.&lt;/p&gt;

&lt;p&gt;Open the relevant file - git adds conflict markers to the relevant code block, highlighting the different code by branch:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// organise-posts.php
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HEAD&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$colour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;red&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$colour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;green&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bugfix&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just delete the code you don’t want, or add an entirely new block. Then &lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt; and commit the file with a new commit message:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git add organise-posts.php
git commit -m &lt;span class=&quot;s2&quot;&gt;&quot;Resolve merge conflict: set things up properly.&quot;&lt;/span&gt;
git push origin master&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;delete-branch&quot;&gt;Delete Branch&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Delete local branch: &lt;code class=&quot;highlighter-rouge&quot;&gt;git branch -d &amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Delete remote branch: &lt;code class=&quot;highlighter-rouge&quot;&gt;git push origin --delete &amp;lt;branchName&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;More obtuse way of remote deletion: &lt;code class=&quot;highlighter-rouge&quot;&gt;git push origin :&amp;lt;branchname&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;remove-a-directory&quot;&gt;Remove a Directory&lt;/h2&gt;
&lt;p&gt;Remove from git (e.g. Bitbucket, GitHub) but leave in place on local filesystem:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git rm -r --cached my-image-folder&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Combine this with an entry into &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; to exclude directories (or files) from the repo.&lt;/p&gt;
</description>
        <pubDate>Sun, 03 Jul 2016 10:55:39 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/07/git-branches/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/07/git-branches/</guid>
      </item>
      
    
      
      <item>
        <title>ArrayAccess PHP Interface</title>
        <description>&lt;p&gt;The PHP &lt;a href=&quot;http://php.net/manual/en/class.arrayaccess.php&quot;&gt;ArrayAccess&lt;/a&gt; class is an interface that allows objects to be accessed as arrays.&lt;/p&gt;

&lt;p&gt;Classes that extend the &lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess&lt;/code&gt; interface must include four core methods:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ArrayAccess&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;cm&quot;&gt;/* Methods */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offsetExists&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offsetGet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offsetSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offsetUnset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mixed&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When the &lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess&lt;/code&gt; class is implemented by a child class with the appropriate methods, data held in the resulting object can be accessed using array syntax.&lt;/p&gt;

&lt;h2 id=&quot;background-php-arrays&quot;&gt;Background: PHP Arrays&lt;/h2&gt;

&lt;p&gt;Arrays in PHP are really ordered maps - a data type that associates keys and values.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;…This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.&lt;/p&gt;

  &lt;p&gt;—&lt;a href=&quot;http://php.net/manual/en/language.types.array.php&quot;&gt;PHP Manual&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PHP arrays hold groups of values which can be identified by position or an associative index.&lt;/p&gt;

&lt;p&gt;Associative array:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'first'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'one'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'second'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'third'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'fourth'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'fifth'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// To access:
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'first'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// echoes 'one'
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Numerically Indexed Array:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'chimi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'changa'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// To access (arrays are zero-indexed):
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&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;c1&quot;&gt;// outputs 'foo'
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// outputs 'chimi'
&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;background-php-objects&quot;&gt;Background: PHP Objects&lt;/h2&gt;

&lt;p&gt;PHP Objects incorporate one or more functions (methods) along with data (properties) into a structure called a &lt;em&gt;class&lt;/em&gt;. Many objects can be instantiated from a single class - the class simply provides the blueprint for the object. Classes are defined with the &lt;code class=&quot;highlighter-rouge&quot;&gt;class&lt;/code&gt; keyword, and new objects are instantiated from classes using the &lt;em&gt;new&lt;/em&gt; keyword.&lt;/p&gt;

&lt;p&gt;PHP also includes a generic empty class called &lt;code class=&quot;highlighter-rouge&quot;&gt;stdClass&lt;/code&gt; - which can be useful for anonymous objects and &lt;a href=&quot;http://krisjordan.com/dynamic-properties-in-php-with-stdclass&quot;&gt;dynamic properties&lt;/a&gt;. This kind of class is useful for storing key-value pairs. You could do this in an array, but value objects have some advantages.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;stdClass&lt;/code&gt; class can be used to create stand-alone objects without first defining a class.&lt;/p&gt;

&lt;p&gt;Value Object Example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$hygiene_obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StdClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$hygiene_obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;armpits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'hairy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$hygiene_obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;feet_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'smelly'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON_PRETTY_PRINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;/pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Adding more data is just a matter of creating a new class property. E.g.
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$hygiene_obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hands&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'grubby'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;armpits&quot;&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;s2&quot;&gt;&quot;hairy&quot;&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;nt&quot;&gt;&quot;feet_status&quot;&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;s2&quot;&gt;&quot;smelly&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The same thing can be achieved by means of an associative array:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$hygiene_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'armpits'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'hairy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'feet status'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'smelly'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$hygiene_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON_PRETTY_PRINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;/pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// To add another element to the array:
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$hygiene_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'hands'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'grubby'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The output is the same as the object example, though there is more leeway with the key names, which can contain spaces:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&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;&quot;armpits&quot;&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;s2&quot;&gt;&quot;hairy&quot;&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;nt&quot;&gt;&quot;feet status&quot;&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;s2&quot;&gt;&quot;smelly&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are a few ways of creating a stdClass object in modern PHP:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$obj1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;stdClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$obj2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;{};&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Instantiate&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;anonymous&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;obj3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Mistake pointed out by Rajesh in comments:&lt;/p&gt;

&lt;strike&gt;$Object = {}&lt;/strike&gt;

&lt;h2 id=&quot;array-access&quot;&gt;Array Access&lt;/h2&gt;
&lt;p&gt;It can sometimes be useful to access objects as arrays. &lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess&lt;/code&gt; is a built in interface class that allows this.&lt;/p&gt;

&lt;p&gt;The interface requires that extending classes use these methods:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess::offsetExists&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess::offsetGet&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess::offsetSet&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ArrayAccess::offsetUnset&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The methods allow us to define a handy data container which can be accessed and amended using the array syntax.&lt;/p&gt;

&lt;h2 id=&quot;arrayaccess-simple-implementation&quot;&gt;ArrayAccess: Simple Implementation&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ArrayAccess&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'first'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;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;s1&quot;&gt;'second'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'third'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;offsetExists&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;offsetGet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&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;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;offsetSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&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;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;offsetUnset&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$offset&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This allows us to access the Object data structure using array syntax:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'test key'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'value'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'chimi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'changa'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'first'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'changed'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The Updated object:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Output of var_dump($object)
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Foo&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;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'container'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'first'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'changed'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'second'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'third'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'test key'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'value'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'chimi'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'changa'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://krisjordan.com/dynamic-properties-in-php-with-stdclass&quot;&gt;Dynamic Properties in PHP and StdClass&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://alanstorm.com/php_array_access&quot;&gt;Article on PHP ArrayAccess interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/2056931/value-objects-vs-associative-arrays-in-php&quot;&gt;S.O. question: Value objects vs associative arrays in PHP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See Also:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://php.net/manual/en/class.countable.php&quot;&gt;PHP Countable Interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://php.net/manual/en/class.countable.php&quot;&gt;Concrete examples of Countable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 26 Jun 2016 20:08:20 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/06/arrayaccess-php-interface/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/06/arrayaccess-php-interface/</guid>
      </item>
      
    
      
      <item>
        <title>Mount Disk Drives in Ubuntu &amp; Raspbian</title>
        <description>&lt;p&gt;Automatically mount disk drives on boot.&lt;/p&gt;

&lt;p&gt;We recently set up a Raspberrry pi as a local fileserver. The Pi is connected to a powered USB hub and a number of hard drives. We use this to backup our systems overnight - the Pi is not the fastest, but the entire system draws less power than a lightbulb.&lt;/p&gt;

&lt;p&gt;To work properly, the connected drives need to be mounted at boot, and this guide outlines how to achieve this.&lt;/p&gt;

&lt;p&gt;You could follow the same procedure for adding drives to any Debian based distro.&lt;/p&gt;

&lt;h2 id=&quot;set-up-drives&quot;&gt;Set Up Drives&lt;/h2&gt;
&lt;p&gt;Use the Disks utility to format and label drives.&lt;/p&gt;

&lt;p&gt;Ext4 is a good choice for a filesystem format if the disk is intended for Linux use only.&lt;/p&gt;

&lt;h2 id=&quot;mount-points&quot;&gt;Mount Points&lt;/h2&gt;
&lt;p&gt;To mount disk drives, first create a mount point(s) and set permissions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir /mnt/disk-1
sudo mkdir /mnt/disk-2

&lt;span class=&quot;c&quot;&gt;# set permissions:&lt;/span&gt;
sudo chmod -R 755 /mnt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;find-drives&quot;&gt;Find Drives&lt;/h2&gt;
&lt;p&gt;There are many ways to determine the drives available to the system:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Get name, size &amp;amp; model, but no UUID&lt;/span&gt;
lsblk -ido KNAME,TYPE,SIZE,MODEL
&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
david@raspberrypi:~ &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;lsblk -ido KNAME,TYPE,SIZE,MODEL
KNAME   TYPE   SIZE MODEL
sda     disk 931.5G External USB-3.0
sdb     disk 931.5G TOURO Mobile    
mmcblk0 disk   7.3G

&lt;span class=&quot;c&quot;&gt;# Get disk name and partition data&lt;/span&gt;
sudo fdisk -l

&lt;span class=&quot;c&quot;&gt;# Get UUID&lt;/span&gt;
ls -l /dev/disk/by-uuid/
&lt;span class=&quot;c&quot;&gt;# Output:&lt;/span&gt;
david@raspberrypi:~ &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ls -l /dev/disk/by-uuid/
total 0
lrwxrwxrwx 1 root root 15 May 10 10:36 04FE-51E9 -&amp;gt; ../../mmcblk0p1
lrwxrwxrwx 1 root root 10 May 10 10:36 76ef1fc2-1bc5-4a2c-950f-43e99c975da8 -&amp;gt; ../../sdb1
lrwxrwxrwx 1 root root 15 May 10 10:36 e6e7f776-11a4-4cd7-b4fd-c44ecdbfcf90 -&amp;gt; ../../mmcblk0p2
lrwxrwxrwx 1 root root 10 May 10 10:36 fba9c513-2117-4245-a41c-f813497b0826 -&amp;gt; ../../sda1

&lt;span class=&quot;c&quot;&gt;# RECOMMENDED - show UUID &amp;amp; disk label for connected drives&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
sudo blkid
&lt;span class=&quot;c&quot;&gt;# Typical output:&lt;/span&gt;
david@raspberrypi:~ &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo blkid
/dev/mmcblk0p1: &lt;span class=&quot;nv&quot;&gt;SEC_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;msdos&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;boot&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;04FE-51E9&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;vfat&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PARTUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8f1eafaf-01&quot;&lt;/span&gt;
/dev/mmcblk0p2: &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;e6e7f776-11a4-4cd7-b4fd-c44ecdbfcf90&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ext4&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PARTUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8f1eafaf-02&quot;&lt;/span&gt;
/dev/sda1: &lt;span class=&quot;nv&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;intenso-backup-1&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;fba9c513-2117-4245-a41c-f813497b0826&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ext4&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PARTUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;972d07b8-01&quot;&lt;/span&gt;
/dev/sdb1: &lt;span class=&quot;nv&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Backup Data&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;76ef1fc2-1bc5-4a2c-950f-43e99c975da8&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ext4&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PARTUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ef9e4c2c-01&quot;&lt;/span&gt;
/dev/mmcblk0: &lt;span class=&quot;nv&quot;&gt;PTUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8f1eafaf&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PTTYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dos&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Disk drives are distinguished by a UUID(universally unique identifier) - we’ll use this number to mount the disks rather than the assigned device name (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sda1&lt;/code&gt;), since the latter might change and the UUID will not.&lt;/p&gt;

&lt;h2 id=&quot;manual-mount&quot;&gt;Manual Mount&lt;/h2&gt;
&lt;p&gt;To mount a drive manually:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mount /dev/sda1 /mnt/disk-1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This won’t be persistent - when the system reboots, the drive will no longer be available.&lt;/p&gt;

&lt;h2 id=&quot;auto-mount-on-boot&quot;&gt;Auto Mount on Boot&lt;/h2&gt;

&lt;p&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fstab&lt;/code&gt; by adding a line for each required disk. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1

&lt;span class=&quot;c&quot;&gt;# additional lines follow - referencing the correct UUID,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# mount point and format for the required disks&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;76ef1fc2-1bc5-4a2c-950f-43e99c975da8&quot;&lt;/span&gt;       /mnt/disk-1       ext4    defaults          0       0
&lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;fba9c513-2117-4245-a41c-f813497b0826&quot;&lt;/span&gt;       /mnt/disk-2       ext4    defaults          0       0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Save, reboot and disks will be mounted automatically on the defined mount points.&lt;/p&gt;
</description>
        <pubDate>Tue, 10 May 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/05/mount-disk-drives-ubuntu-debian/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/05/mount-disk-drives-ubuntu-debian/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Pages for Posts - Show the Content Editor</title>
        <description>&lt;p&gt;When WordPress has a static front page (as set in “Settings” &amp;gt; “Reading”), it is often useful to display introductory content on the page that has been selected for posts.&lt;/p&gt;

&lt;p&gt;The posts page is determined by the ‘page_for_posts’ value in the ‘option_name’ column in the WordPress options table. The ID of this page can be retrieved by:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$page_for_posts_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'page_for_posts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This allows the page content and featured image to be displayed in the template.&lt;/p&gt;

&lt;h2 id=&quot;display-page-content&quot;&gt;Display Page Content&lt;/h2&gt;
&lt;p&gt;By default, the page for posts uses the WordPress &lt;code class=&quot;highlighter-rouge&quot;&gt;home.php&lt;/code&gt; template. To access the page content in this template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$posts_page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'page_for_posts'&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;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;apply_filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'the_content'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$posts_page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;post_content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;where-the-hell-is-the-editor&quot;&gt;Where the Hell is the Editor?&lt;/h2&gt;
&lt;p&gt;WordPress (as of version 4.5.1 anyway) has an extremely annoying characteristic whereby the content editor is not shown on the page for posts &lt;strong&gt;if the &lt;code class=&quot;highlighter-rouge&quot;&gt;post_content&lt;/code&gt; field is empty&lt;/strong&gt;. Instead, you get an annoying message telling you what you already know - that this is the page selected to display blog posts.&lt;/p&gt;

&lt;p&gt;There are two fixes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Temporarily set a different page for blog posts, add some content to your original posts page, and then switch the setting back to the original posts page&lt;/li&gt;
  &lt;li&gt;Remove the annoying message and add back the editor by hooking onto &lt;code class=&quot;highlighter-rouge&quot;&gt;edit_form_after_title&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When I first noticed this, it bugged the hell out of me - since my development site had page content, the editor displayed normally (not so in the staging site).&lt;/p&gt;

&lt;p&gt;The culprit is this little diamond in &lt;code class=&quot;highlighter-rouge&quot;&gt;/wp-admin/edit-form-advanced.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'page_for_posts'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;post_content&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;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'edit_form_after_title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_wp_posts_page_notice'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;remove_post_type_support&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'editor'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The second, less hackish fix:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;/**
 * Add the wp-editor back into WordPress after it was removed in 4.2.2.
 *
 * @see https://wordpress.org/support/topic/you-are-currently-editing-the-page-that-shows-your-latest-posts?replies=3#post-7130021
 * @param $post
 * @return void
 */&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fix_no_editor_on_posts_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$post&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;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'page_for_posts'&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;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&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;nx&quot;&gt;remove_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'edit_form_after_title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_wp_posts_page_notice'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;add_post_type_support&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'page'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'editor'&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;c1&quot;&gt;// This is applied in a namespaced file - so amend this if you're not namespacing
&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'edit_form_after_title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__NAMESPACE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\\fix_no_editor_on_posts_page'&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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Credit for this goes to &lt;a href=&quot;https://wordpress.org/support/topic/you-are-currently-editing-the-page-that-shows-your-latest-posts?replies=3#post-7130021&quot;&gt;crgeary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can’t imagine why this “functionality” has been built in. It would surely be better for WP core to be less opinionated - but at least it’s fairly easy to undo the damage.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://wordpress.org/support/topic/page-for-posts-content-editor&quot;&gt;https://wordpress.org/support/topic/page-for-posts-content-editor&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wordpress.org/support/topic/you-are-currently-editing-the-page-that-shows-your-latest-posts?replies=3#post-7130021&quot;&gt;https://wordpress.org/support/topic/you-are-currently-editing-the-page-that-shows-your-latest-posts?replies=3#post-7130021&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 05 May 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/05/wordpress-content-on-posts-for-pages/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/05/wordpress-content-on-posts-for-pages/</guid>
      </item>
      
    
      
      <item>
        <title>Connect Raspberry Pi Backup Server to Remote Server</title>
        <description>&lt;p&gt;This article describes how to provide a local Raspberry Pi access to a remote server in order to automatically download backup files through an encrypted channel. The connection is limited to read-only access of a specified directory on the remote server.&lt;/p&gt;

&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;The objective is to hold a local copy of backup files. The solution needed to be fully automatic and secure.&lt;/p&gt;

&lt;p&gt;A Raspberry Pi with an external SSD storage drive was used as the local client. Once downloaded, files are accessible across the LAN by SSHing into the Pi.&lt;/p&gt;

&lt;p&gt;The Pi acts as an always-on local fileserver - this periodically connects to a remote server (in this case, a Digital Ocean Ubuntu box) via SSH collecting backup data using &lt;code class=&quot;highlighter-rouge&quot;&gt;rsync&lt;/code&gt;. The setup is low power, cost-effective, secure and runs automatically.&lt;/p&gt;

&lt;p&gt;Because the backup script runs automatically and is unattended, it has to be passwordless. The scope of action on the target machine must be limited to read-only rsync for a specified directory. This limitation is the focus of this article, though I also provide a sample backup script.&lt;/p&gt;

&lt;h2 id=&quot;key-generation&quot;&gt;Key Generation&lt;/h2&gt;
&lt;p&gt;A public-private key pair is required, with the public key added to the target server.&lt;/p&gt;

&lt;p&gt;If one doesn’t already exist, or you need a unique key for some reason, you can generate an RSA key with a specific name:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-keygen -t rsa

&lt;span class=&quot;c&quot;&gt;# Outputs this:&lt;/span&gt;
Enter file &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;which to save the key &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;/home/david/.ssh/id_rsa&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Specify a filename if required. Enter the full path, e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/username/.ssh/local-fileserver&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;comments-in-the-key-file&quot;&gt;Comments in the Key File&lt;/h2&gt;
&lt;p&gt;It can be helpful to have a comment in the key file. When transferred to the target machine, the public key will be appended to the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/username/.ssh/authorized_keys&lt;/code&gt; file. The comment will help distinguish the key.&lt;/p&gt;

&lt;p&gt;If the client machine is compromised, it allows the relevant line to be easily removed from the server &lt;code class=&quot;highlighter-rouge&quot;&gt;authorized_keys&lt;/code&gt; file. If no comment is added, the public key file has username@hostname appended to the key as a default comment.&lt;/p&gt;

&lt;p&gt;To add a comment, just enter text at the end of the public key, separated from the key content by a space.&lt;/p&gt;

&lt;h2 id=&quot;specify-the-correct-key&quot;&gt;Specify the Correct Key&lt;/h2&gt;
&lt;p&gt;If you’re not using the default key file, create an entry in an SSH config file specifying the correct key file for the server that you’re going to connect to.&lt;/p&gt;

&lt;p&gt;You may need to create the config file it it doesn’t exist. The following command will do this in any case, with the file being created when you save (ctrl + o in nano):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /home/username/.ssh/config

&lt;span class=&quot;c&quot;&gt;# Enter the following and save&lt;/span&gt;
Host 192.168.1.XXX
    IdentityFile ~/.ssh/local-fileserver&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;uploading-the-key&quot;&gt;Uploading the Key&lt;/h2&gt;
&lt;p&gt;This can be achieved easily using the &lt;code class=&quot;highlighter-rouge&quot;&gt;ssh-copy-id&lt;/code&gt; command - though the server must obviously allow the connection before the key is set up, so you may need to temporarily amend the servers SSH configuration to reflect this.&lt;/p&gt;

&lt;p&gt;If no keyfile is specified, this command will copy all public keys from the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/username/.ssh&lt;/code&gt; directory, which may not be what you intend.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt; flag can be used to set the specific key file that should be transferred:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-copy-id -i ~/.ssh/local-fileserver.pub username@192.168.1.XXX&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once the key has been transferred, set the SSH config to disallow password login (&lt;code class=&quot;highlighter-rouge&quot;&gt;PasswordAuthentication no&lt;/code&gt;) and restart SSH.&lt;/p&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;
&lt;p&gt;Using an SSH key without a passphrase makes it possible to automate remote tasks - a user-entered passphrase is not required for local key decryption.&lt;/p&gt;

&lt;p&gt;Automation of backup tasks is essential - if backup relies on human intervention, sooner or later it will fail. However, using SSH keys without a passphrase is a security risk - is someone had access to the local backup server, they would be easily able to access the remote server.&lt;/p&gt;

&lt;p&gt;Realistically, this is a pretty low risk. The bad guy would have to break in to your office and know his way round a headless Linux box. We don’t get too many roving bands of rogue systems administrators in this neck of the woods, but just in case…&lt;/p&gt;

&lt;p&gt;SSH allows restriction of the commands that can be executed by a specific set of keys. This is accomplished by editing the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/username/.ssh/authorized_keys&lt;/code&gt; file on the target server.&lt;/p&gt;

&lt;p&gt;A script called rrsync (which stands for restricted rsync) is provided with rsync specifically to ease the restricting keys to be used only for rsync via &lt;code class=&quot;highlighter-rouge&quot;&gt;.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On Ubuntu, the script is located here: /usr/share/doc/rsync/scripts/rrsync.gz. The script needs to be unzipped and installed under &lt;code class=&quot;highlighter-rouge&quot;&gt;usr/local/bin&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Copy the archive rrsync script to /usr/local/bin&lt;/span&gt;
sudo cp /usr/share/doc/rsync/scripts/rrsync.gz  /usr/local/bin/

&lt;span class=&quot;c&quot;&gt;# Unzip the script&lt;/span&gt;
sudo gzip -d   /usr/local/bin/rrsync.gz

&lt;span class=&quot;c&quot;&gt;# Give it correct permissions&lt;/span&gt;
sudo chmod 755 /usr/local/bin/rrsync&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once rrsync is in place, we can lock down access for our SSH key by amending the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/.ssh/authorized_keys&lt;/code&gt; file on the target server.&lt;/p&gt;

&lt;p&gt;Open the public key for the backup user on the target server. This will constitute a single line of text:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /home/backupuser/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Prepend the key data with the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin/rrsync -ro /home/path-to/backup/&quot;&lt;/span&gt;,no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;command=&quot;/usr/local/bin/rrsync ...&quot;&lt;/code&gt; restricts access of that particular public key - only the given command can be executed&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;...-ro /home/path-to/backup/&quot;&lt;/code&gt; gives read-only access to the specified directory&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;no-*&lt;/code&gt; options further restrict what actions can be carried out with the public key.&lt;/li&gt;
  &lt;li&gt;Note that the full path is need to reference rrsync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try and SSH into the Production machine from the Backup server you should now see a message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PTY allocation request failed on channel 0
/usr/local/bin/rrsync: Not invoked via sshd
Use &lt;span class=&quot;s1&quot;&gt;'command=&quot;/usr/local/bin/rrsync [-ro] SUBDIR&quot;'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;front of lines &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /home/backupuser/.ssh/authorized_keys
Connection to 123.45.67.89 closed.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Your script however will be able to gain read-only access, which is good enough to pull-down backup files.&lt;/p&gt;

&lt;h2 id=&quot;rsync-command-rsync-from-the-client&quot;&gt;rsync Command rsync from the Client&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Note: After the above amendment to the authorized_keys file, the final path from the Backup server’s point of view is now &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sample rsync command from the local server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rsync --log-file&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.rsyncd.log --progress -az -H -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 1234&quot;&lt;/span&gt; backupuser@123.456.789.0:/ ~/backup-target-directory&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This specifies:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-a: archive mode; equals -rlptgoD (no -H,-A,-X)&lt;/li&gt;
  &lt;li&gt;-z: Compress file data during the transfer&lt;/li&gt;
  &lt;li&gt;-H: Maintain hardlinks (important due to our incremental backup)&lt;/li&gt;
  &lt;li&gt;-e “ssh -p 1234”: connect via SSH on port 1234&lt;/li&gt;
  &lt;li&gt;See &lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;connect-via-a-scheduled-script&quot;&gt;Connect Via a Scheduled Script&lt;/h2&gt;
&lt;p&gt;Save the following script in &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/sbin&lt;/code&gt; (or create an appropriate symlink:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# On remote, run `rrsync` and prepend this command to the relevant line in `/home/username/.ssh/authorized_keys`:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# `command=&quot;/usr/local/bin/rrsync -ro /home/path/to/backup/&quot;,no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding`&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Run this file from the root crontab on the client machine.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Name of the current script&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The remote server username@ip address, appended with `:/`&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SRC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;remote-username@111.222.111.222:/&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TRG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/mnt/usb1/server-backups/local-backups-dir&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;LOGFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/mnt/usb1/server-backups/pull-backups.log&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date &lt;span class=&quot;s1&quot;&gt;'+%Y-%m-%d at %H:%M:%S'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;ERRORLOG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/mnt/usb1/server-backups/pull-backups-error.log&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# rsync options: follow the symlinks to make a hard backup. Note the custom port&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# specified for SSH which needs to be configured on the remote server.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;-az -H --exclude&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'*.zip'&lt;/span&gt; --exclude&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'debian.cnf'&lt;/span&gt; -e &lt;span class=&quot;s1&quot;&gt;'ssh -p 3333'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Execute the backup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rsync &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SRC&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$TRG&lt;/span&gt; 2&amp;gt; &lt;span class=&quot;nv&quot;&gt;$ERRORLOG&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -eq 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ENDTIME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date &lt;span class=&quot;s1&quot;&gt;'+%H:%M:%S'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; -v MSG &lt;span class=&quot;s2&quot;&gt;&quot;SUCCESS! %s started on: %s, successfully finished at: %s&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TIMESTAMP&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ENDTIME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$MSG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LOGFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ENDTIME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date &lt;span class=&quot;s1&quot;&gt;'+%H:%M:%S'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; -v MSG &lt;span class=&quot;s2&quot;&gt;&quot;ERROR! There was a problem running %s. Started on: %s, ended at: %s. See: %s&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TIMESTAMP&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ENDTIME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ERRORLOG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$MSG&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LOGFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Edit the crontab:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo crontab -l
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Enter the following on a separate line:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# m h  dom mon dow   command&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Run script `my-backup-script` every day at 03:30 am&lt;/span&gt;
30 03 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/local/sbin/my-backup-script
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://manpages.ubuntu.com/manpages/precise/man1/ssh-copy-id.1.html&quot;&gt;Ubuntu Manpage for ssh-copy-id&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 04 May 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/05/secure-connect-raspberry-pi-to-remote-server/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/05/secure-connect-raspberry-pi-to-remote-server/</guid>
      </item>
      
    
      
      <item>
        <title>Accessing Local Fileserver in Ubuntu</title>
        <description>&lt;p&gt;A headless always-on server can be a good way of managing office backups and shared directories.&lt;/p&gt;

&lt;p&gt;These instructions assume that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A linux server has been set up on the network and is accessible via SSH from the client machine (we use a raspberry pi with attached external storage)&lt;/li&gt;
  &lt;li&gt;The machines accessing the server’s filesystem are running Ubuntu desktop (14.04 in this case)&lt;/li&gt;
  &lt;li&gt;The remote filesystem (in this case, the external drive attached to the Pi) is mounted on &lt;code class=&quot;highlighter-rouge&quot;&gt;/mnt&lt;/code&gt; - this is the directory that will be accessible by the client&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install-sshfs-on-the-client-ubuntu-machine&quot;&gt;Install sshfs on the Client Ubuntu Machine&lt;/h2&gt;
&lt;p&gt;SSHFS stands for &lt;strong&gt;SSH File System&lt;/strong&gt;. It is a filesystem client that allows you to interact with files on a remote server or workstation by means of an SSH connection.&lt;/p&gt;

&lt;p&gt;Install SSHFS:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install sshfs&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add your non-sudo user to the &lt;code class=&quot;highlighter-rouge&quot;&gt;fuse&lt;/code&gt; group:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo usermod -a -G fuse username&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Activate group membership change:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;su -l &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;make-and-mount-the-directory&quot;&gt;Make and Mount the Directory&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; -e ~/local-backup-server &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; mkdir --mode 700 ~/local-backup-server
sshf pi@192.168.1.XXX:/mnt &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt;-backup-server&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll need to enter password for the remote host.&lt;/p&gt;

&lt;p&gt;You could also &lt;a href=&quot;/2016/05/secure-connect-raspberry-pi-to-remote-server/&quot;&gt;set up passwordless ssh login to simplify this process&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;unmounting-the-filesystem&quot;&gt;Unmounting the Filesystem&lt;/h2&gt;
&lt;p&gt;To unmount a ssh-mounted directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;fusermount -u &amp;lt;local_mount_point&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;auto-mount&quot;&gt;Auto Mount&lt;/h2&gt;

&lt;p&gt;To automatically mount over ssh on boot:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set up passwordless ssh login&lt;/li&gt;
  &lt;li&gt;Append the following in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fstab&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/fstab
sshfs pi@192.168.1.123:/mnt &amp;lt;local_mount_point&amp;gt; fuse user 0 0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;connect-via-nautilus&quot;&gt;Connect Via Nautilus&lt;/h2&gt;
&lt;p&gt;In Nautilus, open ‘File’ &amp;gt; ‘Connect to Server’ in ‘Server Address’ bar, add &lt;code class=&quot;highlighter-rouge&quot;&gt;sftp://pi@192.168.1.XXX:/mnt&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://xmodulo.com/how-to-mount-remote-directory-over-ssh-on-linux.html&quot;&gt;Mount Remote Directory Over SSH on Linux&lt;/a&gt; - nice article, but the Nautilus information is superceded by the info contained in the link below&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://askubuntu.com/questions/571522/ubuntu-14-04-nautilus-connect-to-server-window-changed&quot;&gt;Connect via Nautilus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 02 May 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/05/access-local-fileserver-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/05/access-local-fileserver-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Deregister Open Sans from WordPress Admin</title>
        <description>&lt;p&gt;WordPress enqueues the Open Sans font in the admin area. This requires making a request to Google Fonts, which obviously isn’t going to work if you are offline.&lt;/p&gt;

&lt;p&gt;This can be very problematic if you’re developing locally and you lose the internet connection. The local site becomes extremely slow as the request to Google Fonts does it’s thing.&lt;/p&gt;

&lt;p&gt;This caught me off guard at first - I blocked my own custom script calls and couldn’t understand what was messing up the local site. It’s WP core calling Google.&lt;/p&gt;

&lt;p&gt;The following hack removes Open Sans from the admin area. Add this code to your theme and uncomment the &lt;code class=&quot;highlighter-rouge&quot;&gt;add_action()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;remove-open-sans&quot;&gt;Remove Open Sans&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Company\Project\Extras&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;/**
 * In case of internet outage
 * @return void
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;remove_open_sans&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;nx&quot;&gt;wp_deregister_style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'open-sans'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;wp_register_style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'open-sans'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&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;c1&quot;&gt;// Un-comment these lines in case of internet outage
// Admin area
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'admin_enqueue_scripts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__NAMESPACE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\\remove_open_sans'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Front end - this may be necessary if using default WP themes
&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'wp_enqueue_scripts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__NAMESPACE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'\\remove_open_sans'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you don’t use namespacing you won’t need &lt;code class=&quot;highlighter-rouge&quot;&gt;__NAMESPACE__ . '\\&lt;/code&gt; in the callback reference.&lt;/p&gt;

&lt;p&gt;Seems like a lot of hassle just for a pretty basic admin font. Maybe the enqueuing function could be wrapped in a conditional that pings Google Fonts?&lt;/p&gt;

&lt;p&gt;I think core should use system fonts by default - if we need to prettify the admin area, that should be a theme-level decision.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://wordpress.org/support/topic/turning-off-open-sans-for-the-38-dashboard&quot;&gt;The answer by Michael Dance&lt;/a&gt;
&lt;a href=&quot;http://blog.milandinic.com/2013/12/04/introducing-disable-google-fonts/&quot;&gt;Sort it with a plugin&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 11 Apr 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/04/remove-open-sans-wordpress-admin/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/04/remove-open-sans-wordpress-admin/</guid>
      </item>
      
    
      
      <item>
        <title>Manipulate Paths and Filenames</title>
        <description>&lt;p&gt;BASH scripts often require manipulation of the pathname of files/directories.&lt;/p&gt;

&lt;h2 id=&quot;get-any-path-in-a-filename&quot;&gt;Get Any Path in a Filename&lt;/h2&gt;
&lt;p&gt;You may need access to the target file’s parent directory, or you may need the file/directory name seperated from it’s path.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Example pathname&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;pathname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;parent/child/target

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;nv&quot;&gt;$pathname&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# returns target&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;nv&quot;&gt;$pathname&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# returns child&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;basename &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;nv&quot;&gt;$pathname&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#returns parent&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;strip-trailing-slash&quot;&gt;Strip Trailing Slash&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/
&lt;span class=&quot;nv&quot;&gt;SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SOURCE_DIR&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# returns test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sun, 10 Apr 2016 16:35:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/04/manipulate-filenames-in-bash/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/04/manipulate-filenames-in-bash/</guid>
      </item>
      
    
      
      <item>
        <title>Bootstrap 3 Header Markup for Sage WordPress Theme</title>
        <description>&lt;p&gt;Sage is an excellent starter theme for WordPress. It comes with Bootstrap connected out-of-the-box, but it does not have a “standard” Bootstrap nav markup. The old Roots theme (Sage’s parent) used to have a &lt;code class=&quot;highlighter-rouge&quot;&gt;NavWalker()&lt;/code&gt; class that extended the WordPress &lt;code class=&quot;highlighter-rouge&quot;&gt;Walker_Nav_Menu()&lt;/code&gt; class to give cleaner menu markup and Bootstrap friendly classes.&lt;/p&gt;

&lt;p&gt;To add the &lt;code class=&quot;highlighter-rouge&quot;&gt;NavWalker()&lt;/code&gt; class, from your theme root, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https://gist.githubusercontent.com/DavidCWebs/445308a3beeffef3d4cf/raw/2187f99bf3e1e9b0f571e507b614ca95ed7df286/nav.php -O lib/nav.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;NB: see update below for a potentially better option.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then replace the code in your &lt;code class=&quot;highlighter-rouge&quot;&gt;templates/header.php&lt;/code&gt; with this (or similar Bootstrap-style markup):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_template_directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/lib/nav.php'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;header&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;banner navbar navbar-inverse navbar-fixed-top navbar-shrink&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;banner&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navbar-header&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navbar-toggle collapsed&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-toggle=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;collapse&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.navbar-collapse&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sr-only&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Toggle navigation'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'sage'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon-bar&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navbar-brand&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;esc_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;home_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bloginfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;nav&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;collapse navbar-collapse&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navigation&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;has_nav_menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'primary_navigation'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;

        &lt;span class=&quot;nx&quot;&gt;wp_nav_menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'theme_location'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'primary_navigation'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'walker'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Roots\Sage\Nav\NavWalker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'menu_class'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nav navbar-nav'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you are using the &lt;code class=&quot;highlighter-rouge&quot;&gt;navbar-fixed-top&lt;/code&gt; class on the navbar element, you’ll need to add the following style rules:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scss&quot; data-lang=&quot;scss&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Offset navbar from top if logged in to allow for the WP admin toolbar
// -----------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.logged-in&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.navbar-fixed-top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;30px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// At the extra small screen and smaller, WP toolbar is taller
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$screen-xs-max&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;nl&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;46px&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// If the navbar is fixed, push down the wrap
// -----------------------------------------------------------------------------
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.navbar-fixed-top&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.wrap&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;78px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;update-september-2016&quot;&gt;Update September 2016&lt;/h2&gt;
&lt;p&gt;The original article didn’t provide the license for the NavWalker. I’ve now included the license in the file docblock.&lt;/p&gt;

&lt;p&gt;The NavWalker above is from quite an old version of Roots - I can’t remember the exact version. The Roots NavWalker class was dropped in March 2015. The link below is for the most recent version, and it may be better for your purposes: &lt;a href=&quot;https://github.com/roots/sage/blob/9efeb67daffa477873d33adafd8b12386c4298ba/lib/nav.php&quot;&gt;https://github.com/roots/sage/blob/9efeb67daffa477873d33adafd8b12386c4298ba/lib/nav.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven’t tried this class, but I will on my next WP project. It looks like it handles custom post types in a better way than the older NavWalker referenced in my original article.&lt;/p&gt;

&lt;p&gt;To copy it into your project, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https://raw.githubusercontent.com/roots/sage/9efeb67daffa477873d33adafd8b12386c4298ba/lib/nav.php -O lib/nav.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sun, 10 Apr 2016 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2016/04/bootstrap-3-nav-wordpress-sage/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/04/bootstrap-3-nav-wordpress-sage/</guid>
      </item>
      
    
      
      <item>
        <title>Parse YAML in PHP Using Symfony YAML</title>
        <description>&lt;p&gt;I do a lot of work in &lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress&lt;/a&gt;. I also build a lot of static websites - both for rapid design in-the-browser and as a low-cost small-business website solution. I mainly use the excellent &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; static site generator.&lt;/p&gt;

&lt;p&gt;Jekyll uses &lt;a href=&quot;http://yaml.org/&quot;&gt;YAML&lt;/a&gt; for config and data files (it can also use CSV format, but that’s another story). WordPress doesn’t use YAML.&lt;/p&gt;

&lt;p&gt;I like YAML because it is very human friendly - the whole team (including non-developers) can easily build YAML config files in a way that you’re not going to see with formats like JSON or XML. This is an example of a YAML array used to create JavaScript variables for use in a Google map:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Map centre Latitude &amp;amp; Longitude&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;52.7157856867271&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;-8.8741735070805&lt;/span&gt;

&lt;span class=&quot;s&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#height: 548px&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set custom colour variables&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;waterColour&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#398A8D&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;landColour&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#dec7c7&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;mainRoadColour&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#777777&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;minorRoadColour&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#a9a9a9&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# A nested array&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;One&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Two&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Three&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the context of Jekyll, you could use this as a data file (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;map.yml&lt;/code&gt;), writing JavaScript variables into &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;head&amp;gt;&lt;/code&gt; something like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cwCentre&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;latitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;longitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zoom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.baseurl}}/{{ site.data.map.mainMarker }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;secondaryMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.baseurl}}/{{ site.data.map.secondaryMarker }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;waterColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.waterColour }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;landColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.landColour }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainRoadColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.mainRoadColour }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;minorRoadColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.minorRoadColour }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.title | escape }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'{{ map_description | markdownify | strip_newlines }}'&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;multi-centre&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;markers&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;secondary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;coords&lt;/span&gt; &lt;span class=&quot;o&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;s1&quot;&gt;'{{ location.name | escape }}'&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;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;latitude&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;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;longitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'{{ location.description | escape }}'&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;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;forloop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;endunless&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;o&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;yaml-in-wordpress&quot;&gt;YAML in WordPress&lt;/h2&gt;

&lt;p&gt;I recently needed to convert a Jekyll site to a WordPress theme. Moving the map config settings required parsing YAML data into a PHP array. Fortunately this can be achieved pretty easily thanks to the &lt;a href=&quot;http://symfony.com/doc/current/components/yaml/introduction.html&quot;&gt;Symfony YAML component&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m a recent convert to &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt;, and find it amazingly powerful. You can add the Symfony YAML component with a single composer command.&lt;/p&gt;

&lt;h2 id=&quot;add-symfonyyaml-using-composer&quot;&gt;Add Symfony/YAML Using Composer&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;composer require symfony/yaml&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When you run this, composer will add a new &lt;code class=&quot;highlighter-rouge&quot;&gt;symfony/yaml&lt;/code&gt; directory under the project &lt;code class=&quot;highlighter-rouge&quot;&gt;vendor&lt;/code&gt; directory. It will also add the relevant namespace to the &lt;code class=&quot;highlighter-rouge&quot;&gt;autoload_psr4.php&lt;/code&gt; file, so that the new class will be autoloaded.&lt;/p&gt;

&lt;h2 id=&quot;using-the-yaml-parser&quot;&gt;Using the YAML parser&lt;/h2&gt;

&lt;p&gt;To read the YAML contents of the config fiel into a PHP array:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Yaml\Parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$yaml&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yaml&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file_get_contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_template_directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/assets/map.yml'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For the YAML content presented above, the following will be output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;$value = array (
  'latitude' =&amp;gt; 52.715785686727102,
  'longitude' =&amp;gt; -8.8741735070804992,
  'zoom' =&amp;gt; 15,
  'waterColour' =&amp;gt; '#398A8D',
  'landColour' =&amp;gt; '#dec7c7',
  'mainRoadColour' =&amp;gt; '#777777',
  'minorRoadColour' =&amp;gt; '#a9a9a9',
  'test' =&amp;gt;
  array (
    0 =&amp;gt; 'One',
    1 =&amp;gt; 'Two',
    2 =&amp;gt; 'Three',
  ),
);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This array can be passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_localize_script()&lt;/code&gt; when enqueuing the map script.&lt;/p&gt;

&lt;p&gt;The WordPress/PHP way would be to collect such data from a form on an admin page, storing the data in the &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_options&lt;/code&gt; table. However taking variables from YAML files can be a good way to quickly port settings, which might even be used as defaults. It might also be a good way to configure certain project settings.&lt;/p&gt;
</description>
        <pubDate>Mon, 21 Mar 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/03/parse-yaml-in-php/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/03/parse-yaml-in-php/</guid>
      </item>
      
    
      
      <item>
        <title>Undo a Git add</title>
        <description>&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt; Adds file contents to the index - preparing the content staged for the next commit.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The “index” holds a snapshot of the content of the working tree, and it is this snapshot that is taken as the contents of the next commit.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://git-scm.com/docs/git-add&quot;&gt;git docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before running the commit command, you use &lt;code class=&quot;highlighter-rouge&quot;&gt;add&lt;/code&gt; to add new/modified files to the index.&lt;/p&gt;

&lt;p&gt;It’s common that you accidentally add a file - and it can be very important to remove it again.&lt;/p&gt;

&lt;h2 id=&quot;remove-a-single-file&quot;&gt;Remove a Single File&lt;/h2&gt;
&lt;p&gt;To remove a given file only from the current index:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git reset filename&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;undo-git-add-althogether&quot;&gt;Undo &lt;code class=&quot;highlighter-rouge&quot;&gt;git add&lt;/code&gt; Althogether&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git reset&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 01 Mar 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/03/undo-git-add/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/03/undo-git-add/</guid>
      </item>
      
    
      
      <item>
        <title>Exim4 Send Only Mailserver</title>
        <description>&lt;p&gt;Exim4 is a lightweight mail transfer agent that is easy to set up and configure.&lt;/p&gt;

&lt;p&gt;These instructions focus on Ubuntu 14.04 Server.&lt;/p&gt;

&lt;p&gt;Setting up a send-only mailserver on Ubuntu is relatively straightforward. The tricky bit is ensuring that mail sent by the server is not labelled as spam.&lt;/p&gt;

&lt;h2 id=&quot;exim4-installation&quot;&gt;Exim4 Installation&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Upgrade system: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get -y upgrade&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Install Exim4 and dependencies: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get -y install exim4&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Run the config script: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo dpkg-reconfigure exim4-config&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;exim4-configuration&quot;&gt;Exim4 Configuration&lt;/h2&gt;
&lt;p&gt;Make selections with arrow keys - select “Ok” with tab key&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Select: ‘internet site; mail is sent and received directly using SMTP’&lt;/li&gt;
  &lt;li&gt;Enter FQDN: &lt;code class=&quot;highlighter-rouge&quot;&gt;hostname.yourdomain.com&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;SMTP Listener: enter &lt;code class=&quot;highlighter-rouge&quot;&gt;127.0.0.1&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;127.0.0.1; ::1&lt;/code&gt;(for IPv6 support)&lt;/li&gt;
  &lt;li&gt;Mail destinations - list FQDN, local hostname, &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost.localdomain&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;localhost&lt;/code&gt; (see NOTE below)&lt;/li&gt;
  &lt;li&gt;Relay Options: Leave blank - hit tab to highlight “Ok”, then enter&lt;/li&gt;
  &lt;li&gt;Follow up Screen to Relay Options: Leave blank, hit “Ok”&lt;/li&gt;
  &lt;li&gt;DNS Queries: Keep DNS queries to a minimum? select “No”&lt;/li&gt;
  &lt;li&gt;Delivery method: Select “Maildir format in home directory”&lt;/li&gt;
  &lt;li&gt;Choose default &lt;strong&gt;unsplit&lt;/strong&gt; config file by entering “No”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Ubuntu 14.04, that’s it - there is no option to specify postmaster mail recipients. This &lt;strong&gt;must&lt;/strong&gt; be set - or email clients like gmail will place sent emails in the recipient’s spam folder. Most tutorials refer to a final configuration window - but this will not appear on Ubuntu 14.04.&lt;/p&gt;

&lt;h2 id=&quot;specify-postmaster-address&quot;&gt;Specify Postmaster Address&lt;/h2&gt;
&lt;p&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/email-addresses&lt;/code&gt; to include:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;username: no-reply@yourdomain.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Replace “username” with the system username that is running the mail process.&lt;/li&gt;
  &lt;li&gt;Enter new username/email values on separate lines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;test-email-from-command-line&quot;&gt;Test email from Command Line:&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;echo &quot;Hello - this is a test!&quot; | mail -s Testing you@yourweb.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;access-logs&quot;&gt;Access Logs&lt;/h2&gt;
&lt;p&gt;The main log is held in: &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/exim4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This directory is owned by &lt;code class=&quot;highlighter-rouge&quot;&gt;Debian-exim:adm&lt;/code&gt; - and is hence inaccessible, unless you log in as root.&lt;/p&gt;

&lt;p&gt;Add your user to the &lt;code class=&quot;highlighter-rouge&quot;&gt;adm&lt;/code&gt; group to access logs:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo usermod -a -G adm username&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can then access the main exim4 log at: &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/exim4/mainlog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code class=&quot;highlighter-rouge&quot;&gt;eximstats&lt;/code&gt; to see a text report:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;eximstats /var/log/exim4/mainlog&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;post-installation-configuration&quot;&gt;Post Installation Configuration&lt;/h2&gt;
&lt;p&gt;The initial configuration settings are stored in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/exim4/update-exim4.conf.conf&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;To re-configure the program, either re-run the configuration wizard: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo dpkg-reconfigure exim4-config&lt;/code&gt; or manually edit this file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/exim4/update-exim4.conf.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;After editing the settings, you need to generate the master configuration file:&lt;/strong&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo update-exim4.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart the exim4 service:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo /etc/init.d/exim4 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-reverse-dns&quot;&gt;Set Up Reverse DNS&lt;/h2&gt;
&lt;p&gt;Reverse DNS maps an IP address to a domain name - and is crucial to avoid having outgoing mail labelled as spam.&lt;/p&gt;

&lt;p&gt;The reverse DNS zone must be created on the “authoritative DNS nameserver for the main IP address of your server” - so to set reverse DNS, you need control over the nameserver for your main IP address.&lt;/p&gt;

&lt;p&gt;For Linode VPS:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Log in to Linode Manager&lt;/li&gt;
  &lt;li&gt;Select the Linode&lt;/li&gt;
  &lt;li&gt;Select “Remote Access”&lt;/li&gt;
  &lt;li&gt;Enter the domain name in the hostname field and click “lookup”&lt;/li&gt;
  &lt;li&gt;A message should appear stating that a match has been found between your domain and your IP address&lt;/li&gt;
  &lt;li&gt;Select “yes” for the desired address (IPv4 &amp;amp; IPv6 will need to be selected separately)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it!&lt;/p&gt;

&lt;h2 id=&quot;spf-records&quot;&gt;SPF Records&lt;/h2&gt;
&lt;p&gt;Publishing a Sender Policy Framework (SPF) Record in your &lt;strong&gt;domain’s&lt;/strong&gt; DNS specifies which server IP addresses are allowed to send emails from your domain.&lt;/p&gt;

&lt;p&gt;Having a properly set up SPF record makes it less likely that outgoing mail will be tagged as spam.&lt;/p&gt;

&lt;p&gt;Although it is best practice is to publish SPF records via DNS as both a SPF and TXT record, the DNS management utilities for many registrars (e.g. Heart Internet, Blacknight) only provide for the addition of txt records. For a good description of SPF as TXT records, see &lt;a href=&quot;http://mxtoolbox.com/problem/spf/txt-record&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following SPF record, added as a TXT record is a reasonable sample:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;spf1 a mx ip4:123.45.678.90 mx:mail.yourdomain.com ~all&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;bizzarre-spam-issues&quot;&gt;Bizzarre Spam Issues&lt;/h2&gt;
&lt;p&gt;After following the above setup, I noticed the following weird behaviour with regard to gmail recipients.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Send mail from WordPress to a gmail account (the &lt;code class=&quot;highlighter-rouge&quot;&gt;www-data user&lt;/code&gt;, not aliased in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/email-addresses&lt;/code&gt;): Success&lt;/li&gt;
  &lt;li&gt;Send mail from command line (&lt;code class=&quot;highlighter-rouge&quot;&gt;echo &quot;This is a test.&quot; | mail -s Testing emailaddress68@gmail.com&lt;/code&gt;) to same address: Designated as Spam&lt;/li&gt;
  &lt;li&gt;Send the same mail from command line to a &lt;strong&gt;different&lt;/strong&gt; gmail account: Success&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were two SPF records on the DNS settings for the domain - which isn’t allowed. Deactivated the old one.&lt;/p&gt;

&lt;p&gt;In addition, the header in gmail showed that gmail was looking for an IP address in the ipv6 format…so I added this to the SPF record.&lt;/p&gt;

&lt;p&gt;To determine ipv6 for the server: &lt;code class=&quot;highlighter-rouge&quot;&gt;ip -6 addr show&lt;/code&gt; - the public IP is on the line labelled ‘scope global’.&lt;/p&gt;

&lt;p&gt;You can only add a single SPF record - but ipv6 and ipv4 IP addresses can be included. Sample TXT record for SPF:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;spf1 a mx ip4:123.45.67.890 ip6:3a00:9a00::b14d:12aa:ab67:a3c5/64 mx:mail.yourdomain.com ~all&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;send-email-from-command-line&quot;&gt;Send Email From Command Line&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello - this is a test!&quot;&lt;/span&gt; | mail -s Testing you@yourweb.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.debian.org/PkgExim4UserFAQ&quot;&gt;Exim4 wiki&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://bradthemad.org/tech/notes/exim_cheatsheet.php&quot;&gt;Brad the Mad’s Exim Cheatsheet&lt;/a&gt; - switch &lt;code class=&quot;highlighter-rouge&quot;&gt;exim4&lt;/code&gt; for &lt;code class=&quot;highlighter-rouge&quot;&gt;exim&lt;/code&gt; if necessary&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/networking/dns/setting-reverse-dns&quot;&gt;Setup Reverse DNS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-an-spf-record-to-prevent-spoofing-improve-e-mail-reliability&quot;&gt;Digital Ocean tutorial on SPF&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.unlocktheinbox.com/&quot;&gt;Unlock the Inbox&lt;/a&gt;: Info on email configuration&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.spfwizard.net/&quot;&gt;SPF Wizard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.unlocktheinbox.com/senderid-wizard/&quot;&gt;Unlock the Inbox Sender ID Wizard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.unlocktheinbox.com/spfwizard/&quot;&gt;Unlock the Inbox SPF Wizard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/mscorp/safety/content/technologies/senderid/wizard/&quot;&gt;&lt;del&gt;MS SPF Wizard&lt;/del&gt;&lt;/a&gt;: Page removed, thanks to Henry for pointing this out&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-the-send-only-mail-server-exim-on-ubuntu-12-04&quot;&gt;Exim4 setup &amp;amp; config&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.simplehelp.net/2008/12/01/how-to-send-email-from-the-linux-command-line/&quot;&gt;Send email from Command Line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 01 Mar 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/03/exim4-send-only-mailserver/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/03/exim4-send-only-mailserver/</guid>
      </item>
      
    
      
      <item>
        <title>iptables Ubuntu Firewall</title>
        <description>&lt;p&gt;iptables is a firewall programme that allows you to control server traffic on a Linux system.&lt;/p&gt;

&lt;p&gt;By default, iptables allows all traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: &lt;a href=&quot;https://help.ubuntu.com/community/UFW&quot;&gt;UFW&lt;/a&gt; is the default firewall configuration tool for Ubuntu - UFW (disabled by default) can simplify firewall setup.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;display-iptables-info&quot;&gt;Display iptables Info&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Quick list&lt;/span&gt;
sudo iptables -S

&lt;span class=&quot;c&quot;&gt;# iptables list with numbered lines&lt;/span&gt;
iptables -nL --line-numbers&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;add-rules&quot;&gt;Add Rules&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;-A&lt;/code&gt; flag denotes that the rule will be appended - added as the last rule in the chain.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;-I&lt;/code&gt; flag denotes that the rule will be inserted - the precise line-number for insertion can also be controlled.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Allow connection on post 80 by appending a rule&lt;/span&gt;
sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow incoming traffic on the default SSH port(22):&lt;/span&gt;
sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow SSH connection on a non-standard port (1234)&lt;/span&gt;
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 1234 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow ping from a specified IP address, inserted at a specific line in the chain:&lt;/span&gt;
sudo iptables -I INPUT 9 -s x.x.x.x -p ICMP --icmp-type 8 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Insert a rule as the first rule in the INPUT chain&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This rule allows already established (and related) connections&lt;/span&gt;
iptables -I INPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;delete-rules&quot;&gt;Delete Rules&lt;/h2&gt;
&lt;p&gt;Delete a rule in a chain using the &lt;code class=&quot;highlighter-rouge&quot;&gt;-D&lt;/code&gt; option. You need to specify the chain, and the rule. The rule is either specified by entering the whole rule to match, or the line number of the rule to delete. Rules are numbered from the top of each chain, starting with 1.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Delete by specifying rule&lt;/span&gt;
sudo iptables -D INPUT -p tcp -m tcp --dport 80 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Delete by specifying the line number in the INPUT chain - deletes the 9th rule in the chain&lt;/span&gt;
sudo iptables -D INPUT 9&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;view-iptables-log&quot;&gt;View iptables Log&lt;/h2&gt;
&lt;p&gt;Logs are generated by the kernel, so they go to the file that receives kernel logs: &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/kern.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To view iptables denial in real time, run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tail -f /var/log/kern.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;blocking-an-ip&quot;&gt;Blocking an IP&lt;/h2&gt;
&lt;p&gt;To block an attackers ip address (e.g. 1.2.3.4) enter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;iptables -A INPUT -s 1.2.3.4 -j DROP
iptables -A INPUT -s 192.168.0.0/24 -j DROP&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;make-iptables-rules-persistent&quot;&gt;Make iptables Rules Persistent&lt;/h2&gt;
&lt;p&gt;The iptables rulesets are held in memory, which means that they are not persistent across system reboots.&lt;/p&gt;

&lt;p&gt;The easiest way to persist rules on Ubuntu is probably the &lt;code class=&quot;highlighter-rouge&quot;&gt;iptables-persistent&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;To install:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install iptables-persistent

&lt;span class=&quot;c&quot;&gt;# Start the service!&lt;/span&gt;
sudo service iptables-persistent start&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After starting, new ruleset files will be created: &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/iptables/rules.v4&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/iptables/rules.v6&lt;/code&gt;. These contain IPv4 and IPv6 rules respectively.&lt;/p&gt;

&lt;p&gt;After amending iptables (or ip6tables), save changes to those files:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6

&lt;span class=&quot;c&quot;&gt;# Restart service to read the changes in:&lt;/span&gt;
sudo service iptables-persistent start&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See &lt;a href=&quot;http://askubuntu.com/questions/119393/how-to-save-rules-of-the-iptables&quot;&gt;http://askubuntu.com/questions/119393/how-to-save-rules-of-the-iptables&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;import-or-restore-a-ruleset&quot;&gt;Import or Restore a Ruleset&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Save ruleset&lt;/span&gt;
sudo iptables-save &amp;gt; /tmp/ruleset-v4
sudo ip6tables-save &amp;gt; /tmp/ruleset-v6

&lt;span class=&quot;c&quot;&gt;# Restore ruleset&lt;/span&gt;
sudo iptables-restore &amp;lt; /tmp/ruleset-v4
sudo ip6tables-restore &amp;lt; /tmp/ruleset-v6&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There is a good basic ruleset from Linode &lt;a href=&quot;https://www.linode.com/docs/security/securing-your-server#basic-iptables-rulesets-for-ipv4-and-ipv6&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;sample-iptables-ruleset&quot;&gt;Sample iptables Ruleset&lt;/h2&gt;
&lt;p&gt;Restoring this ruleset may provide a decent starting point. The default policy is DROP - this means that the rules contain exceptions - if the specific condition is met, the packet is accepted.&lt;/p&gt;

&lt;p&gt;The ruleset below allows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Loopback traffic&lt;/li&gt;
  &lt;li&gt;Inbound traffic from established connections&lt;/li&gt;
  &lt;li&gt;HTTP &amp;amp; HTTPS connections (internet)&lt;/li&gt;
  &lt;li&gt;SSH connection on a custom port number&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;filter
-N LOGGING
&lt;span class=&quot;c&quot;&gt;# Allow all loopback traffic (lo0)&lt;/span&gt;
-A INPUT -i lo -j ACCEPT
&lt;span class=&quot;c&quot;&gt;# Reject traffic to localhost that doesn't originate from lo0&lt;/span&gt;
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT

&lt;span class=&quot;c&quot;&gt;# Allow inbound from established connections&lt;/span&gt;
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow HTTP and HTTPS connections from anywhere&lt;/span&gt;
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow ping from the home server only&lt;/span&gt;
-A INPUT -s 1.1.1.1 -p icmp -m icmp --icmp-type 8 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# Allow SSH traffic on custom port 4321&lt;/span&gt;
-A INPUT -p tcp -m state --state NEW -m tcp --dport 4321 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 4321 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;# If the packet has made it this far without being accepted, it's going to be&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# dropped. The logging chain will record some data about the packet first.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The relevant log file is `/var/log/kern.log`.&lt;/span&gt;
-A INPUT -j LOGGING
-A LOGGING -p icmp -m limit --limit 5/min -j LOG --log-prefix &lt;span class=&quot;s2&quot;&gt;&quot;iptables-denied ICMP: &quot;&lt;/span&gt; --log-level 7
-A LOGGING -p udp -m limit --limit 5/min -j LOG --log-prefix &lt;span class=&quot;s2&quot;&gt;&quot;iptables-denied UDP: &quot;&lt;/span&gt; --log-level 7
-A LOGGING -p tcp -m limit --limit 5/min -j LOG --log-prefix &lt;span class=&quot;s2&quot;&gt;&quot;iptables-denied TCP: &quot;&lt;/span&gt; --log-level 7
-A LOGGING -j DROP
COMMIT&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;notes-re-iptables-and-ufw&quot;&gt;Notes Re iptables and UFW&lt;/h2&gt;
&lt;p&gt;If iptables rules have been added, they will appear before the UFW rules - and the first rules will take precedence.&lt;/p&gt;

&lt;p&gt;Packets drop through a chain of rules. If the iptables INPUT chain rule has a default drop policy, it matches every remaining packet that reaches it. With iptables, order is important. The first rule that natches a packet of data is the one that will be applied.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Once a decision is made to accept a packet, no more rules affect it. As our rules allowing ssh and web traffic come first, as long as our rule to block all traffic comes after them, we can still accept the traffic we want. All we need to do is put the rule to block all traffic at the end.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://help.ubuntu.com/community/IptablesHowTo&quot;&gt;Ubuntu Community iptables HowTo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;procedure-to-flush-rules&quot;&gt;Procedure to Flush Rules&lt;/h2&gt;
&lt;p&gt;If you need to flush firewall rules, first ensure that the remote connection can be maintained:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set default policies to &quot;ACCEPT&quot;&lt;/span&gt;
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

&lt;span class=&quot;c&quot;&gt;# Flush the `nat` and `mangle` tables:&lt;/span&gt;
sudo iptables -t nat -F
sudo iptables -t mangle -F

&lt;span class=&quot;c&quot;&gt;# Flush all chains&lt;/span&gt;
sudo iptables -F

&lt;span class=&quot;c&quot;&gt;# Delete all non-default chains&lt;/span&gt;
sudo iptables -X&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you’ve been trying UFW, you may end up with a number of extraneous statements prepended “ufw-“. To remove these:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Remove ufw rules from iptables&lt;/span&gt;
sudo iptables -D ufw-after-forward
sudo iptables -X ufw-after-forward
sudo iptables -X ufw-after-input
sudo iptables -X ufw-after-logging-forward
sudo iptables -X ufw-after-logging-input
sudo iptables -X ufw-after-logging-output
sudo iptables -X ufw-after-output
sudo iptables -X ufw-before-forward
sudo iptables -X ufw-before-input
sudo iptables -X ufw-before-logging-forward
sudo iptables -X ufw-before-logging-input
sudo iptables -X ufw-before-logging-output
sudo iptables -X ufw-before-output
sudo iptables -X ufw-reject-forward
sudo iptables -X ufw-reject-input
sudo iptables -X ufw-reject-output
sudo iptables -X ufw-track-forward
sudo iptables -X ufw-track-input
sudo iptables -X ufw-track-output&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You might need to do something similar for ip6tables. &lt;a href=&quot;http://blog.derakkilgo.com/2011/01/22/the-complicated-process-for-removing-the-uncomplicated-firewall/&quot;&gt;Bash script for this procedure&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/IptablesHowTo&quot;&gt;Ubuntu Community iptablesHowTo&lt;/a&gt; - ggood resource, with good info on logging&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-list-and-delete-iptables-firewall-rules&quot;&gt;Digital Ocean - list &amp;amp; delete iptables rules&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-iptables-on-ubuntu-14-04&quot;&gt;Digital Ocean -  Set Up Firewall using iptables on Ubuntu 14.04&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-14-04&quot;&gt;Firewall with UFW on Ubuntu&lt;/a&gt; - good tutorial, UFW as alternative to amending iptables directly&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://fideloper.com/iptables-tutorial&quot;&gt;iptables Essentials&lt;/a&gt; - Digital Ocean&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://fideloper.com/iptables-tutorial&quot;&gt;Good iptables tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hackertarget.com/attacking-wordpress/&quot;&gt;Testing with nmap - attacking WordPress&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.thegeekstuff.com/2012/08/iptables-log-packets/&quot;&gt;Log dropped packets&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-psad-to-detect-network-intrusion-attempts-on-an-ubuntu-vps&quot;&gt;Use psad to detect network intrusion attempts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-fail2ban-works-to-protect-services-on-a-linux-server&quot;&gt;Intro to Fail2ban&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.lammertbies.nl/comm/info/iptables.html&quot;&gt;Intro to iptables setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/security/securing-your-server#basic-iptables-rulesets-for-ipv4-and-ipv6&quot;&gt;Good Linode article on securing a server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 25 Feb 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/02/iptables-ubuntu-firewall/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/02/iptables-ubuntu-firewall/</guid>
      </item>
      
    
      
      <item>
        <title>Wget Commands</title>
        <description>&lt;p&gt;Wget is a free utility for download of files from the web. It is non-interactive, so can work in the background.&lt;/p&gt;

&lt;h2 id=&quot;download-a-file-from-github-or-gisthub&quot;&gt;Download a file from GitHub or Gisthub&lt;/h2&gt;
&lt;p&gt;Click “raw” to access the URL of the raw file.&lt;/p&gt;

&lt;p&gt;To download into the current directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https://link-to-raw-file.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;download-a-list-of-pages&quot;&gt;Download a List of Pages&lt;/h2&gt;
&lt;p&gt;This can be a useful way to collect images from a service like Unsplash. Image download links can be added on a separate line in a manifest file, which can be used by wget:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget -i manifest&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;download-all-images-from-a-webpage&quot;&gt;Download All Images From a webpage&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget -nd -H -p -A jpg,jpeg,png,gif -e &lt;span class=&quot;nv&quot;&gt;robots&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;off http://www.website.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-nd&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;--no-directories&lt;/code&gt; When retriving recursively, wget will not create a hierarchy of directories - all files will be saved to the current directory.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-H&lt;/code&gt; Allow spanning across hosts when doing recursive retrieving - be careful since foreign hosts may link to other hosts, sucking down more data than intended.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-p&lt;/code&gt; Page requisites - allows wget to downlaod all files necessary to display a HTML page, including inline images, sounds and stylesheets.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-A&lt;/code&gt; Specify a comma separated list of files to accept - in this example, image files.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-e&lt;/code&gt; Execute command as if it were part of the file .wgetrc. Executed after .wgetrc, therefore taking precedence - needed for the &lt;code class=&quot;highlighter-rouge&quot;&gt;robots=off&lt;/code&gt; flag.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;robots=off&lt;/code&gt; Turns off robots exclusion - by default wget respects robot exclusion rules set in the site &lt;code class=&quot;highlighter-rouge&quot;&gt;/robots.txt&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.computerhope.com/unix/wget.htm&quot;&gt;wget syntax guide&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/wget/manual/&quot;&gt;wget man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 Feb 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/02/wget/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/02/wget/</guid>
      </item>
      
    
      
      <item>
        <title>Semantic Bootstrap Layout Classes with an Offset</title>
        <description>&lt;p&gt;Making CSS classes descriptive, or semantic, can help improve code maintainability by describing an elements purpose, rather than it’s presentational function.&lt;/p&gt;

&lt;p&gt;People level this as a criticism against Bootstrap (and other CSS frameworks) - where column names are presentational rather than semantic. In other words, in a typical Bootstrap project the main content area might have a class name like &lt;code class=&quot;highlighter-rouge&quot;&gt;.col-md-8&lt;/code&gt;, which is not semantic.&lt;/p&gt;

&lt;p&gt;Fortunately, Bootstrap makes it pretty easy to define semantic classes that apply the built-in presentational logic, by use of the &lt;code class=&quot;highlighter-rouge&quot;&gt;make-x-column()&lt;/code&gt; mixins.&lt;/p&gt;

&lt;h2 id=&quot;sage---example-of-semantically-defining-classes&quot;&gt;Sage - Example of Semantically Defining Classes&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://roots.io/sage/&quot;&gt;Sage&lt;/a&gt; WordPress starter theme (a great starting point for WordPress projects) defines a &lt;code class=&quot;highlighter-rouge&quot;&gt;.main&lt;/code&gt; and a &lt;code class=&quot;highlighter-rouge&quot;&gt;.sidebar&lt;/code&gt; class out of the box.&lt;/p&gt;

&lt;p&gt;The column widths for these elements can then be set in a &lt;code class=&quot;highlighter-rouge&quot;&gt;_variables.scss&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;offset-sidebar&quot;&gt;Offset Sidebar&lt;/h2&gt;
&lt;p&gt;I’ve modified the Sage definition of &lt;code class=&quot;highlighter-rouge&quot;&gt;.main&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;.sidebar&lt;/code&gt; to add an offset to the sidebar, using the additional Bootstrap mixin &lt;code class=&quot;highlighter-rouge&quot;&gt;make-sm-column-offset()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I find the offset really good for user experience - constraining the main content area generally makes for greater readability, and the extra whitespace between content and sidebar can reduce the sensation of clutter.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scss&quot; data-lang=&quot;scss&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Grid system
&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.main&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// No sidebar, `.main` is full width
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------------
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;make-sm-column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$main-sm-columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// `.main` is contained by the `.sidebar-primary` parent class - this class is
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// added to the &amp;lt;body&amp;gt; of pages that display the sidebar. If a sidebar displays,
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// `.main` can take a reduced width.
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------------
&lt;/span&gt;  &lt;span class=&quot;nc&quot;&gt;.sidebar-primary&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// `.main` is narrower by 2 columns, to give room for the offset
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;make-sm-column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$main-sm-columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$sidebar-sm-columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&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;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.sidebar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Set the width, then the offset, using Bootstrap mixins
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------------
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;make-sm-column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sidebar-sm-columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;@include&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;make-sm-column-offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.w3.org/QA/Tips/goodclassnames&quot;&gt;W3C on class names&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://willschenk.com/bootstrap-advanced-grid-tricks/&quot;&gt;Description of semantic classes in Bootstrap&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://brettjankord.com/2013/02/09/thoughts-on-semantic-html-class-names-and-maintainability/&quot;&gt;Thoughts on Semantic Classes - Brett Jankord&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.sitepoint.com/css-frameworks-semantic-class-names/&quot;&gt;CSS Frameworks &amp;amp; semantic class names&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 13 Feb 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/02/semantic-bootstrap-classes-offsets/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/02/semantic-bootstrap-classes-offsets/</guid>
      </item>
      
    
      
      <item>
        <title>Get Column Names from a WordPress Database Table</title>
        <description>&lt;p&gt;Get a comma-separated string of all column names (Field names) for a given MySQL table.&lt;/p&gt;

&lt;p&gt;Useful when working with custom tables.&lt;/p&gt;

&lt;h2 id=&quot;method-1-using-wpdb-getcol&quot;&gt;Method 1: Using &lt;code class=&quot;highlighter-rouge&quot;&gt;$wpdb-&amp;gt;get_col()&lt;/code&gt;&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// An array of Field names
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;DESC &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&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;c1&quot;&gt;// Implode to a string suitable for inserting into the SQL query
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;', '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;method-2-using-wpdb-getresults&quot;&gt;Method 2: Using &lt;code class=&quot;highlighter-rouge&quot;&gt;$wpdb-&amp;gt;get_results()&lt;/code&gt;&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$cols_sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;DESCRIBE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$all_objects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cols_sql&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$all_objects&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$object&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;c1&quot;&gt;// Build an array of Field names
&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Field&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;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;', '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example&quot;&gt;Example&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Company\Project\Includes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$fields&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'all'&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;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Build an array of all field names for this table
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;DESC &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&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;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;implode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;', '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$existing_columns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'all'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$fields&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SELECT &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; FROM &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&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;c1&quot;&gt;// Build a query for specific fields if these are passed in to the function
&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that the &lt;code class=&quot;highlighter-rouge&quot;&gt;implode()&lt;/code&gt; function can accept parameters in any order. Probably best to use it as shown, to maintain consistency with &lt;code class=&quot;highlighter-rouge&quot;&gt;explode()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/4165195/mysql-query-to-get-column-names&quot;&gt;Good description of various methods, with pros &amp;amp; cons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 09 Feb 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/02/wordpress-get-table-fieldnames/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/02/wordpress-get-table-fieldnames/</guid>
      </item>
      
    
      
      <item>
        <title>Atom Crashes on Startup When A Repo has Uncommitted Changes</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://atom.io&quot;&gt;Atom&lt;/a&gt; is a free open source text editor “A hackable text editor for the 21st Century”. I really like it. It is fast, reliable, and hackable.&lt;/p&gt;

&lt;p&gt;I recently experienced an odd crash when attempting to open a particular directory. The circumstances were a bit unusual and probably won’t crop up again, but I’m documenting this anyway to avoid repeating myself if it does reoccur.&lt;/p&gt;

&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;Building a git based generator to speed up my WordPress plugin workflow.&lt;/p&gt;

&lt;p&gt;The generator scaffolds out a namespaced WordPress plugin. The project is closely based on the &lt;a href=&quot;https://github.com/DevinVinson/WordPress-Plugin-Boilerplate&quot;&gt;WordPress Plugin Boilerplate&lt;/a&gt;, except the class structure conforms to PSR-4 autoloading standards, and uses a Composer autoloader. Plugins devloped this way are not intended for distribution - they are for our own projects, where we always control the production environment.&lt;/p&gt;

&lt;p&gt;Namespacing &amp;amp; autoloading may not be the “WordPress way”, but it encourages small, tidy classes and I like it a lot.&lt;/p&gt;

&lt;p&gt;The workflow will involve invoking a BASH script that git clones the starter project, copies it, and renames files and file references within the new project. The script also gives the option to create and push to a new GitHub repo for the project.&lt;/p&gt;

&lt;p&gt;The idea is to run one command, enter the new plugin name, and be ready to go.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;During testing my BASH script successfully:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cloned the starter project&lt;/li&gt;
  &lt;li&gt;Copied and renamed the project&lt;/li&gt;
  &lt;li&gt;Amended filenames and references to files within the project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To save time, I chose NOT to set up a new git repo.&lt;/p&gt;

&lt;p&gt;When trying to open the new project in Atom, Atom crashed. Safe mode did not help. Atom would open other directories without issue.&lt;/p&gt;

&lt;h2 id=&quot;the-clue&quot;&gt;The Clue&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/atom/atom/issues/3627&quot;&gt;This issue&lt;/a&gt; reported a crash when trying to open a file that had been modified but not committed.&lt;/p&gt;

&lt;h2 id=&quot;verification&quot;&gt;Verification&lt;/h2&gt;
&lt;p&gt;On temporarily renaming the &lt;code class=&quot;highlighter-rouge&quot;&gt;.git&lt;/code&gt; directory, the project repo opened in Atom without any problem.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;
&lt;p&gt;When files were modified by my script, they contained uncommitted changes. I think this was what triggered the crash.&lt;/p&gt;

&lt;p&gt;In this case, when creating a new project, if the user does not choose to create a new repo the original &lt;code class=&quot;highlighter-rouge&quot;&gt;.git&lt;/code&gt; directory should be removed.&lt;/p&gt;
</description>
        <pubDate>Thu, 04 Feb 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/02/atom-crash-uncommitted-git-changes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/02/atom-crash-uncommitted-git-changes/</guid>
      </item>
      
    
      
      <item>
        <title>Fail2Ban and WordPress</title>
        <description>&lt;p&gt;Fail2ban is generally used to prevent brute force break-in attempts against SSH servers. These attempts typically come from automated scripts attempting multiple username/password combinations. Fail2ban acts by automatically identifying and acting against possible break-in attempts.&lt;/p&gt;

&lt;p&gt;For SSH, you could cut these kind of attacks off by disallowing password login, requiring server administrators to connect by means of a public/private key pair. You might also use a non-standard port for SSH connections - but don’t rely on this alone!&lt;/p&gt;

&lt;p&gt;Fail2ban helps to secure SSH connections by dropping the connection after a defined number of unsuccessful login attempts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fail2ban is not an excuse to use weak authentication methods.&lt;/strong&gt; You should protect important services with public/private authentication and/or very strong passwords.&lt;/p&gt;

&lt;h2 id=&quot;how-fail2ban-works&quot;&gt;How Fail2ban Works&lt;/h2&gt;
&lt;p&gt;Fail2ban is basically a sin bin for hosts. It scans log files (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/auth.log&lt;/code&gt;) and bans IP addresses that cause multiple authentication errors.&lt;/p&gt;

&lt;p&gt;When Fail2ban detects that the number of failed login attempts from an IP have exceeded the pre-defined threshold, it updates the system firewall rules to reject new connections from those IP addresses for a set length of time. When the ban time is up, the ban is lifted.&lt;/p&gt;

&lt;p&gt;Fail2ban allows you to configure:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A white-list of IP addresses to avoid accidental lockouts&lt;/li&gt;
  &lt;li&gt;The threshold number of unsuccessful logins&lt;/li&gt;
  &lt;li&gt;The time period over which malicious attempts are considered&lt;/li&gt;
  &lt;li&gt;The length of stay in the sin-bin&lt;/li&gt;
  &lt;li&gt;The precise actions taken - e.g. you can set up an email detailing RIPE data for each ban&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;get-fail2ban&quot;&gt;Get Fail2ban&lt;/h2&gt;
&lt;p&gt;On Ubuntu, this is very simple:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
sudo apt-get install fail2ban&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;fail2ban-configuration&quot;&gt;Fail2ban Configuration&lt;/h2&gt;
&lt;p&gt;Fail2ban config files are located in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a default config file: &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.conf&lt;/code&gt; - but DO NOT edit this, since the file can be modified by upgrades.&lt;/p&gt;

&lt;p&gt;Copy the file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now configure Fail2ban by editing &lt;code class=&quot;highlighter-rouge&quot;&gt;jail.local&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/fail2ban/jail.local&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Within this file you can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create an &lt;code class=&quot;highlighter-rouge&quot;&gt;ignoreip&lt;/code&gt; whitelist&lt;/li&gt;
  &lt;li&gt;Set the &lt;code class=&quot;highlighter-rouge&quot;&gt;bantime&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set the conditions to determine illegitimate users: &lt;code class=&quot;highlighter-rouge&quot;&gt;findtime&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;maxretry&lt;/code&gt; i.e. how many retries are allowed over a set time period&lt;/li&gt;
  &lt;li&gt;Set the MTA and email address if you are adding email notifications to your Fail2ban action&lt;/li&gt;
  &lt;li&gt;Set the action that Fail2ban takes when an illegitimate login attempt is detected&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;wordpress--fail2ban&quot;&gt;WordPress &amp;amp; Fail2ban&lt;/h2&gt;
&lt;p&gt;Beyond SSH, “brute force” activity focusing on WordPress login pages (e.g. yoursite.com/wp-admin) is very common. You could lock down access to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-login.php&lt;/code&gt; by &lt;a href=&quot;/2015/10/restrict-access-by-ip-apache-2-4/&quot;&gt;white-listing IP addresses&lt;/a&gt;. However, this isn’t always possible:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The site might be member-focused, with lots of members logging in from variable IP addresses&lt;/li&gt;
  &lt;li&gt;The client/site administrator may not have a fixed IP address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benefit of using Fail2ban is that you can protect multiple sites on a server. Fail2ban is &lt;a href=&quot;https://github.com/fail2ban/fail2ban/blob/master/ChangeLog&quot;&gt;actively developed and maintained&lt;/a&gt;, and you should probably be running it on your Linux box anyway.&lt;/p&gt;

&lt;p&gt;Unsuccessful WordPress log in attempts are not normally logged to the server logfiles - so they are not picked up on by Fail2ban.&lt;/p&gt;

&lt;p&gt;To set up Fail2ban with WordPress you need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add malicious login attempts to the &lt;code class=&quot;highlighter-rouge&quot;&gt;auth.log&lt;/code&gt; for all managed WordPress installations&lt;/li&gt;
  &lt;li&gt;Properly configure Fail2ban to act on unauthorized login attempts - add the IP of malicious users to a firewall “deny” directive&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;add-failed-login-attempts-to-authlog&quot;&gt;Add Failed Login Attempts to &lt;code class=&quot;highlighter-rouge&quot;&gt;auth.log&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Add &lt;a href=&quot;https://wordpress.org/plugins/wp-fail2ban&quot;&gt;WP fail2ban&lt;/a&gt; as a must-use plugin. This writes unsuccessful login attempts to &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/auth.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By defining the appropriate constant in &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;, the plugin can also block WordPress user enumeration attempts.&lt;/p&gt;

&lt;p&gt;User enumeration is when a quesry string like &lt;code class=&quot;highlighter-rouge&quot;&gt;http://yoursite.com/?author=1&lt;/code&gt; is entered. On an unprotected WordPress site, this will return an archive page for user with an ID of 1 (usually the first administrative user), displaying the Username. This gives a would-be hacker the benefit of knowing your username.&lt;/p&gt;

&lt;p&gt;If using the WP fail2ban plugin, this is easily blocked. Just add this line to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;define( 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION', true );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For academic interest, here’s how this is achieved within the plugin:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'WP_FAIL2BAN_BLOCK_USER_ENUMERATION'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;WP_FAIL2BAN_BLOCK_USER_ENUMERATION&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;nx&quot;&gt;add_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'redirect_canonical'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$redirect_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$requested_url&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;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;intval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'author'&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;nb&quot;&gt;openlog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;\syslog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LOG_NOTICE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Blocked user enumeration attempt from '&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remote_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;bail&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$redirect_url&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;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-a-fail2ban-filter&quot;&gt;Set Up a Fail2ban Filter&lt;/h2&gt;
&lt;p&gt;A Fail2ban filter contains a regular expression which is used to define a logged event as a break-in attempt.&lt;/p&gt;

&lt;p&gt;Filters should be added to the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/filter.d&lt;/code&gt; directory. The regexes in the filter MUST match the log entries for failed login attempts. The WP fail2ban plugin has a sample filter - this can be added to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/filter.d/wordpress.conf&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /etc/fail2ban/filter.d
wget http://plugins.svn.wordpress.org/wp-fail2ban/trunk/wordpress.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-a-wordpress-jail&quot;&gt;Set Up a WordPress Jail&lt;/h2&gt;
&lt;p&gt;A WordPress jail can be created for Fail2ban. The jail is defined in a configuration file located in the directory &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.d&lt;/code&gt;. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/fail2ban/jail.d/wordpress.conf

&lt;span class=&quot;c&quot;&gt;# Add the following to the jail config file:&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;wordpress]
enabled &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;filter &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; wordpress
logpath &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/auth.log
port &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; http,https&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The jail configuration sets the filter that will be used, as well as the path to the log file.&lt;/p&gt;

&lt;h2 id=&quot;fail2ban-action&quot;&gt;Fail2Ban Action&lt;/h2&gt;
&lt;p&gt;When the failed login attempt has been logged, a Fail2ban action should be configured.&lt;/p&gt;

&lt;p&gt;There are several default actions available in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.local&lt;/code&gt;. The most basic action involves adding a new firewall rule, but you can configure email notifications as part of the Fail2ban action.&lt;/p&gt;

&lt;h2 id=&quot;unban-an-ip-address&quot;&gt;Unban an IP Address&lt;/h2&gt;

&lt;p&gt;To unban an IP address from the WordPress Fail2Ban jail:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo fail2ban-client &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;wordpress unbanip 11.111.11.11&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;Make sure that the regex in the WordPress filter matches the string that is written into the log file on authentication failure.&lt;/p&gt;

&lt;p&gt;It can be useful to run &lt;code class=&quot;highlighter-rouge&quot;&gt;tail -f /var/log/auth.log&lt;/code&gt; and run a few failed logins. You’ll see the log entries in real time, and can cross reference this with the regex in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/filter.d/wordpress.conf&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;automation&quot;&gt;Automation&lt;/h2&gt;
&lt;p&gt;It is a good idea to apply these measures to all WordPress sites that are hosted on public-facing servers. Once Fail2ban has been configured for a server, the logging functionality just needs to be enabled for all new sites. If you have a site creation script, the &lt;code class=&quot;highlighter-rouge&quot;&gt;WP Fail2ban&lt;/code&gt; mu-plugin could be added automatically whenever a new site is created.&lt;/p&gt;

&lt;h2 id=&quot;logging-repeated-entries&quot;&gt;Logging: Repeated Entries&lt;/h2&gt;
&lt;p&gt;The Rsyslog daemon should be configured to turn OFF the &lt;code class=&quot;highlighter-rouge&quot;&gt;$RepeatedMsgReduction&lt;/code&gt; configuration parameter.
To achieve this, amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/rsyslog&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Use sed to amend the config setting&lt;/span&gt;
sudo sed -i &lt;span class=&quot;s1&quot;&gt;'s/RepeatedMsgReduction\ on/RepeatedMsgReduction\ off/'&lt;/span&gt; /etc/rsyslog.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…alternatively, edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/rsyslog.conf&lt;/code&gt; manually.&lt;/p&gt;

&lt;p&gt;By default in Ubuntu 14.04, repeat messages are suppressed in the rsyslog daemon. This can allow attackers to slip through - we need the consecutive failed authentication messages to appear in the log. The rsyslog project team actually recommend setting this parameter to “off”.&lt;/p&gt;

&lt;p&gt;My testing has shown that with repeat message suppression turned on, Fail2Ban is less effective at banning offenders - repeat messages don’t seem to be counted if they come through straight after the previous attempt. I found this very confusing until I realised that the RepeatedMsgReduction should be turned off.&lt;/p&gt;

&lt;p&gt;After this amendment, restart the rsyslog daemon:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service rsyslog restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;alternative-wordpress-protection-limit-login-attempts&quot;&gt;Alternative WordPress Protection: Limit Login Attempts&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://wordpress.org/plugins/limit-login-attempts/&quot;&gt;Limit Login Attempts&lt;/a&gt; is a very useful plugin that basically limits login attempts (as you’d expect!). It provides a simple interface that allows you to control the lockout time, number of retries allowed etc.&lt;/p&gt;

&lt;p&gt;Whilst &lt;strong&gt;extremely&lt;/strong&gt; useful, the plugin is not actively maintained (it has more than 1 million downloads, but was last updated 3 years ago).&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.fail2ban.org/wiki/index.php/MANUAL_0_8&quot;&gt;Fail2ban Manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hackertarget.com/wordpress-user-enumeration/&quot;&gt;WordPress User Enumeration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bjornjohansen.no/using-fail2ban-with-wordpress&quot;&gt;Using Fail2ban with WordPress&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-14-04&quot;&gt;Fail2ban on Ubuntu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://charles.lecklider.org/wordpress/wp-fail2ban&quot;&gt;Charles Lecklider, wp-fail2ban&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/14.04/serverguide/firewall.html&quot;&gt;Ubuntu UFW Firewall&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=440037&quot;&gt;Repeated Message Logging&lt;/a&gt;: bug report&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.rsyslog.com/doc/v7-stable/configuration/action/rsconf1_repeatedmsgreduction.html&quot;&gt;Notes on rsyslog daemon config&lt;/a&gt; w.r.t repeat messages.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 27 Jan 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/01/fail2ban-wordpress/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/01/fail2ban-wordpress/</guid>
      </item>
      
    
      
      <item>
        <title>Open Graph Tags for Jekyll</title>
        <description>&lt;h2 id=&quot;the-jekyll-open-graph-include&quot;&gt;The Jekyll Open Graph Include&lt;/h2&gt;
&lt;p&gt;Save this as an include - for example, as &lt;code class=&quot;highlighter-rouge&quot;&gt;/_includes/og.html&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:site_name&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% if page.title %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ page.title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% else %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.title %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;article&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:type&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% else %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;website&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:type&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.excerpt %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ page.excerpt }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:description&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% else %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.description }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:description&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.url %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.url }}{{ page.url }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:url&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.date %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ page.date | date_to_xmlschema }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;article:published_time&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.url }}/about/&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;article:author&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.featured-image %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.url }}/{{ page.featured-image }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:image&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% else %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.url }}/assets/images/medium-images/main-site-image.jpg&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;og:image&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
{% endif %}
{% if page.categories %}
  {% for category in page.categories limit:1 %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ category }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;article:section&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  {% endfor %}
{% endif %}
{% if page.tags %}
  {% for tag in page.tags %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ tag }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;article:tag&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  {% endfor %}
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;document-head&quot;&gt;Document Head&lt;/h2&gt;
&lt;p&gt;Call the include in the document head:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{% include general/og.html %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;gotchas&quot;&gt;Gotchas&lt;/h2&gt;
&lt;p&gt;Facebook generally needs URLs - which must include ‘http’ or ‘https’ (rather than a relative link) - hence the use of &lt;code class=&quot;highlighter-rouge&quot;&gt;site.url&lt;/code&gt; throughout rather than &lt;code class=&quot;highlighter-rouge&quot;&gt;site.baseurl&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;facebook-debugging&quot;&gt;Facebook Debugging&lt;/h2&gt;
&lt;p&gt;You can have Facebook scrape your page using the &lt;a href=&quot;https://developers.facebook.com/tools/debug/og/object/&quot;&gt;Developers debugging utility&lt;/a&gt;. This provides lots of useful information regarding how Facebook views your document.&lt;/p&gt;
</description>
        <pubDate>Tue, 19 Jan 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/01/og-tags-for-jekyll/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/01/og-tags-for-jekyll/</guid>
      </item>
      
    
      
      <item>
        <title>Inserting Images in Markdown Jekyll Posts</title>
        <description>&lt;p&gt;It’s often useful to add images in the body of a markdown document. While the featured image of a post or page can be specified in the YAML frontmatter, you can also call images directly within the markdown document.&lt;/p&gt;

&lt;p&gt;This article outlines how to achieve this within Jekyll.&lt;/p&gt;

&lt;h2 id=&quot;kramdown-image-syntax&quot;&gt;Kramdown Image Syntax&lt;/h2&gt;
&lt;p&gt;Insert the following into your .md document:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-markdown&quot; data-lang=&quot;markdown&quot;&gt;&lt;span class=&quot;p&quot;&gt;![&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;image-title-here&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;/path/to/image.jpg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;{:class=&quot;img-responsive&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The methodology for adding a class to the image took a bit of hunting.&lt;/p&gt;

&lt;p&gt;Extra attributes (like the image class attribute) are added via span and block inline-attribute-list (IAL). As well as adding a class, you could specify image width and height.&lt;/p&gt;

&lt;p&gt;Because the image is an inline (span level) element, the IAL needs to be on the same line. If you add it on the following line, it will wrap the image in a &amp;lt;p&amp;gt; tag and apply the class to that element.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://kramdown.gettalong.org/quickref.html&quot;&gt;Kramdown Quick Ref&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://kramdown.gettalong.org/syntax.html#block-ials&quot;&gt;Kramdown Block IALs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://kramdown.gettalong.org/syntax.html#images&quot;&gt;Complete Kramdown Reference for Images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 19 Jan 2016 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2016/01/images-in-kramdown-jekyll/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2016/01/images-in-kramdown-jekyll/</guid>
      </item>
      
    
      
      <item>
        <title>Recursively Find and Replace Strings in Files</title>
        <description>&lt;p&gt;It can be useful to amend strings within project files - perhaps when spinning up a new project from a generated starting point.&lt;/p&gt;

&lt;p&gt;I use this when setting the namespace of a new project.&lt;/p&gt;

&lt;h2 id=&quot;combine-find-and-sed&quot;&gt;Combine &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Gnu &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; allows you to find files within a directory tree.&lt;/p&gt;

&lt;p&gt;Sed is a unix utility that parses and transforms text, and is available for most operating systems.&lt;/p&gt;

&lt;h2 id=&quot;replace-string-in-all-project-files&quot;&gt;Replace String in All Project Files&lt;/h2&gt;
&lt;p&gt;The command shown below is for Ubuntu.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;find /path/to/my-project -type f -exec sed -i &lt;span class=&quot;s1&quot;&gt;'s/OldString/NewString/g'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; will execute &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt; substituting {} with the filename found - in this case, all files under &lt;code class=&quot;highlighter-rouge&quot;&gt;/path/to/my-project&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;\;&lt;/code&gt; ending means that &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt; is passed one file at a time.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://ss64.com/bash/exec.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Exec&lt;/code&gt;: execute a command&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/sed/manual/sed.txt&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt;, a stream editor.&lt;/a&gt; Parse &amp;amp; Transform text&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 15 Dec 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/12/find-and-replace-word-instances-recursively/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/12/find-and-replace-word-instances-recursively/</guid>
      </item>
      
    
      
      <item>
        <title>Find Ruby Gems</title>
        <description>&lt;p&gt;To find the location of Ruby gems on your system enter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gem environment&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The installation directory is denoted by &lt;code class=&quot;highlighter-rouge&quot;&gt;INSTALLATION DIRECTORY&lt;/code&gt;. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;INSTALLATION DIRECTORY: /home/david/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 08 Dec 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/12/find-ruby-gems/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/12/find-ruby-gems/</guid>
      </item>
      
    
      
      <item>
        <title>Retrieve and Display WordPress ACF Repeater Field Data</title>
        <description>&lt;p&gt;The &lt;a href=&quot;http://www.advancedcustomfields.com/pro/&quot;&gt;Advanced Custom Fields Pro&lt;/a&gt; WordPress plugin has a repeater field function that allows content editors to add multiple field values.&lt;/p&gt;

&lt;p&gt;For example, the site editor might need the ability to select files that will be available for download. Setting up an ACF repeater field allows as many files as necessary to be associated with the post being edited.&lt;/p&gt;

&lt;p&gt;The ACF interface is excellent and very user friendly - but I prefer to use native WordPress functionality to retrieve and display data that has been stored by ACF. This ensures that the data will still be displayed even if the client disables or removes the ACF plugin.&lt;/p&gt;

&lt;p&gt;This tutorial documents how to retrieve and display a repeater field called &lt;code class=&quot;highlighter-rouge&quot;&gt;downloads&lt;/code&gt; with a single subfield called &lt;code class=&quot;highlighter-rouge&quot;&gt;file&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The file attachment IDs are retrieved, and these are used to build an array that contains the title, permalink, file type and file size.&lt;/p&gt;

&lt;p&gt;This array is used to construct a list of “click to download” links.&lt;/p&gt;

&lt;h2 id=&quot;class-methods&quot;&gt;Class Methods&lt;/h2&gt;
&lt;p&gt;This example shows the data-retrieval function and a function that builds a &lt;code class=&quot;highlighter-rouge&quot;&gt;ul&lt;/code&gt; element to display files for download.&lt;/p&gt;

&lt;p&gt;I have shown them as static methods in a class, but if you are using procedural programming rather than an OOP approach you could drop the functions in your theme’s
&lt;code class=&quot;highlighter-rouge&quot;&gt;functions.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;If you do this, you should prefix your functions with a pseudo namespace, and change the reference to &lt;code class=&quot;highlighter-rouge&quot;&gt;self::get_repeater_file_download()&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;the_attached_downloads()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;retrieve-the-data&quot;&gt;Retrieve the Data&lt;/h2&gt;
&lt;p&gt;This method fetches data from the &lt;code class=&quot;highlighter-rouge&quot;&gt;postmeta&lt;/code&gt; table and returns a multi-dimensional array.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;/**
 * Build file data for downloadable files
 *
 * Iterates through database entries in the postmeta table that have been saved
 * in the Advanced Custom Fields repeater field format:
 * `fieldname_' . $i . '_subfieldname`.
 *
 * @param  string|int $post_ID The current post ID
 * @return array               Array of file data
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_repeater_file_download&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_ID&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;c1&quot;&gt;// The number of entries for this repeater field
&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$files&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_post_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'downloads'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$files&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;k&quot;&gt;return&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;nv&quot;&gt;$file_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&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;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;o&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;nv&quot;&gt;$file_ID&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_post_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_the_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'downloads_'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'_file'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_attached_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file_ID&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$file_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'filesize'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;size_format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;filesize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&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;s1&quot;&gt;'filetype'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_check_filetype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'ext'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'url'&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_get_attachment_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file_ID&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_the_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file_ID&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;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;display-data&quot;&gt;Display Data&lt;/h2&gt;
&lt;p&gt;This builds the HTML for a list of downloadable links using data from the method above.&lt;/p&gt;

&lt;p&gt;The download attached files &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; can be displayed within template files by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;?php ClassName::the_attached_downloads(); ?&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;  
&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;/**
 * Build a ul with attached file titles and links
 *
 * @return string HTML list of downloadable files
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;the_attached_downloads&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;nv&quot;&gt;$downloads&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_repeater_file_download&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_the_ID&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;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$downloads&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;k&quot;&gt;return&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;nb&quot;&gt;ob_start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Downloads&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Click the link to download.&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$downloads&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$download&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$download&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'url'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$download&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; (&lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$download&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'filetype'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;, &lt;span class=&quot;cp&quot;&gt;&amp;lt;?=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$download&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'filesize'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;)
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ob_get_clean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 03 Dec 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/12/retrieve-and-display-wordpress-acf-repeater-field-data/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/12/retrieve-and-display-wordpress-acf-repeater-field-data/</guid>
      </item>
      
    
      
      <item>
        <title>Rebuild WordPress Site From Incremental Backup</title>
        <description>&lt;p&gt;This involves creating a new database, importing the backed up database, replacing site files and connecting site files to the new database.&lt;/p&gt;

&lt;h2 id=&quot;create-blank-database&quot;&gt;Create Blank Database&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Replace &quot;new_db_name&quot;, &quot;new_user&quot; and &quot;12345&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You will need to enter the MySQL password for the root user&lt;/span&gt;
mysql -u root -p -e &lt;span class=&quot;s2&quot;&gt;&quot;create database new_db_name; GRANT ALL PRIVILEGES ON new_db_name.* TO new_user@localhost IDENTIFIED BY '12345'&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;import-copy-of-backup-database&quot;&gt;Import Copy of Backup Database&lt;/h2&gt;
&lt;p&gt;After creating a new database, make sure you are logged out of the MySQL shell (ctrl + c), then enter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql -u root -p new_db_name &amp;lt; database_to_import.sql&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-files&quot;&gt;Set Up Files&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Add backup site files to document root&lt;/li&gt;
  &lt;li&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt; - enter the correct database name, user and password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If deploying to the same URL, you are done. If you are migrating the site, you need to edit database entries, since the site URL will be different.&lt;/p&gt;

&lt;h2 id=&quot;migration-amend-database&quot;&gt;Migration: Amend Database&lt;/h2&gt;
&lt;p&gt;Start a MySQL session for the new database:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql -u root -p new_db_name&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check you’re working in the right database:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;mysql&amp;gt; &lt;/span&gt;SELECT DATABASE&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;;
+---------------+
| DATABASE&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;    |
+---------------+
| new_db_name  |
+---------------+&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Amend the following code block to reflect your old and new domain names:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;UPDATE wp_options SET option_value &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; replace&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;option_value, &lt;span class=&quot;s1&quot;&gt;'http://old-domain.com'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'http://new-domain.com'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; WHERE option_name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'home'&lt;/span&gt; OR option_name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'siteurl'&lt;/span&gt;;
UPDATE wp_posts SET guid &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; replace&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;guid, &lt;span class=&quot;s1&quot;&gt;'http://old-domain.com'&lt;/span&gt;,&lt;span class=&quot;s1&quot;&gt;'http://new-domain.com'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;;
UPDATE wp_posts SET post_content &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; replace&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;post_content, &lt;span class=&quot;s1&quot;&gt;'http://old-domain.com'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'http://new-domain.com'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;;
UPDATE wp_postmeta SET meta_value &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; replace&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;meta_value,&lt;span class=&quot;s1&quot;&gt;'http://old-domain.com'&lt;/span&gt;,&lt;span class=&quot;s1&quot;&gt;'http://new-domain.com'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;NB: if you use a custom database table prefix, replace the &lt;code class=&quot;highlighter-rouge&quot;&gt;wp_&lt;/code&gt; prefixes in the example code block&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;migration-flush-rewrite-rules&quot;&gt;Migration: Flush Rewrite Rules&lt;/h2&gt;
&lt;p&gt;Log in to the new site, navigate to Settings » Permalinks and click save. Pretty permalinks should now work.&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Nov 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/11/rebuild-wordpress-from-backup/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/11/rebuild-wordpress-from-backup/</guid>
      </item>
      
    
      
      <item>
        <title>Jekyll Contact Forms Using Formspree</title>
        <description>&lt;p&gt;Forms need somewhere to be submitted to, and form data needs to be processed.&lt;/p&gt;

&lt;p&gt;For WordPress/PHP sites, this is pretty trivial. The form posts data to a PHP script, which takes certain actions - adds data to the database, sends email, etc.&lt;/p&gt;

&lt;p&gt;If you’re embedding a form on a Static site (in this case Jekyll), you could create a PHP form processor provided that the server is running PHP. A simpler alternative would be to use a third party email based service like &lt;a href=&quot;https://formspree.io/&quot;&gt;Formspree&lt;/a&gt; - which allows 1000 emails per month on the free tier.&lt;/p&gt;

&lt;h2 id=&quot;formspree-form-markup&quot;&gt;Formspree Form Markup&lt;/h2&gt;
&lt;p&gt;This page is testing a Formspree contact form.&lt;/p&gt;

&lt;p&gt;The form markup is as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;form&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-horizontal&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;action=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//formspree.io/youremail@yourweb.com&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;method=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;fieldset&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;placeholder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Your Name&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;email&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_replyto&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;placeholder=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Your Email&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-control&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;textarea&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Your Message&lt;span class=&quot;nt&quot;&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;form-group&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;submit&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Send&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_gotcha&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;display:none&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/fieldset&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once you submit the form for the first time, you’ll get a confirmation email to prevent spam submissions from random sites.&lt;/p&gt;

&lt;p&gt;This page is testing the Formspree form.&lt;/p&gt;

&lt;h2 id=&quot;contact-form&quot;&gt;Contact Form&lt;/h2&gt;
&lt;p&gt;Get in touch!&lt;/p&gt;
&lt;form class=&quot;form-horizontal&quot; action=&quot;//formspree.io/david@carawebs.com&quot; method=&quot;POST&quot;&gt;
  &lt;fieldset&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;input name=&quot;name&quot; placeholder=&quot;Your Name&quot; type=&quot;text&quot; class=&quot;form-control&quot; /&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;input name=&quot;_replyto&quot; placeholder=&quot;Your Email&quot; type=&quot;email&quot; class=&quot;form-control&quot; /&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;textarea class=&quot;form-control&quot; id=&quot;textarea&quot; name=&quot;message&quot;&gt;Your Message&lt;/textarea&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-check&quot;&gt;
  &lt;label class=&quot;form-check-label&quot;&gt;
    &lt;input class=&quot;form-check-input&quot; type=&quot;radio&quot; name=&quot;exampleRadios&quot; id=&quot;exampleRadios1&quot; value=&quot;option1&quot; checked=&quot;&quot; /&gt;
    Option one is this and that&amp;mdash;be sure to include why it's great
  &lt;/label&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-check&quot;&gt;
    &lt;label class=&quot;form-check-label&quot;&gt;
      &lt;input class=&quot;form-check-input&quot; type=&quot;radio&quot; name=&quot;exampleRadios&quot; id=&quot;exampleRadios2&quot; value=&quot;option2&quot; /&gt;
      Option two can be something else and selecting it will deselect option one
    &lt;/label&gt;
  &lt;/div&gt;
  &lt;div class=&quot;form-group&quot;&gt;
    &lt;input value=&quot;Submit Form&quot; type=&quot;submit&quot; class=&quot;btn ghost&quot; /&gt;
  &lt;/div&gt;
  &lt;input name=&quot;_next&quot; value=&quot;//dev-notes.eu/thanks/&quot; type=&quot;hidden&quot; /&gt;
  &lt;input name=&quot;_gotcha&quot; style=&quot;display:none&quot; type=&quot;text&quot; /&gt;
  &lt;/fieldset&gt;
&lt;/form&gt;
</description>
        <pubDate>Wed, 25 Nov 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/11/jekyll-contact-form-formspree/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/11/jekyll-contact-form-formspree/</guid>
      </item>
      
    
      
      <item>
        <title>JavaScript Variables from Markdown Includes in Jekyll</title>
        <description>&lt;p&gt;The problem: Adding JavaScript variables in the document head makes them available to scripts that execute on the page. Building JavaScript variables using Jekyll &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; tags results in a breaking error due to a sneaky trailing blank line that is rendered to the output HTML. This can be fixed by filtering the output with the &lt;code class=&quot;highlighter-rouge&quot;&gt;strip_newlines&lt;/code&gt; liquid filter.&lt;/p&gt;

&lt;h2 id=&quot;javascript-variables&quot;&gt;JavaScript Variables&lt;/h2&gt;

&lt;p&gt;Within Jekyll, we can add variables that have been set in &lt;code class=&quot;highlighter-rouge&quot;&gt;_config.yml&lt;/code&gt; or in other data files. This allows us to easily define variables in a central location.&lt;/p&gt;

&lt;p&gt;In this case, we are passing variables to a Google map script. These variables will be used to customise map styles, markers and infowindows. The variables could easily be held in a CSV format file to allow easy data entry by non-technical people. The description field for the main info window needs to be properly formatted HTML - so it can’t easily or conveniently be held in a data file field. It should be edited in a markdown file which is then rendered to the page. The reference to this markdown file is held in the data file &lt;code class=&quot;highlighter-rouge&quot;&gt;/_data/map.yml&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;s&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;52.741865&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;-8.772812&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;548px&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;main-brand-colour&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#398A8D&quot;&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;main-marker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;assets/images/marker.png&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;secondary-marker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;assets/images/marker-2.png&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Cozy Cottage&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# description refers to a markdown file that will be the source&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# for a HTML string included in the JS variable&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/content/contact/map-description.md&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;html-include&quot;&gt;HTML Include&lt;/h2&gt;

&lt;p&gt;The following file, &lt;code class=&quot;highlighter-rouge&quot;&gt;map.html&lt;/code&gt;, is included in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag conditionally on the page title being contained in an array of map-displaying pages:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;#map-canvas&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
{% capture map_description %}{% include {{site.data.map.description }}%}{% endcapture %}
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cwCentre&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;latitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;longitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zoom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.baseurl}}/{{ site.data.map.main-marker }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;secondaryMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.baseurl}}/{{ site.data.map.secondary-marker }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainBrandColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.main-brand-colour }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{{ site.data.map.title | escape }}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{{ map_description | markdownify | strip_newlines }}&quot;&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cwCentre&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;markers&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;coords&lt;/span&gt; &lt;span class=&quot;o&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;s1&quot;&gt;'{{ location.name | escape }}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,{{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;latitude&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;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;longitude&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{{ location.description | escape }}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;forloop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;endunless&lt;/span&gt; &lt;span class=&quot;o&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;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;o&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;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://maps.googleapis.com/maps/api/js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;strip-newlines&quot;&gt;Strip Newlines&lt;/h2&gt;

&lt;p&gt;If you don’t add the &lt;code class=&quot;highlighter-rouge&quot;&gt;strip_newlines&lt;/code&gt; filter to the markdownified output, the JavaScript variable will have an additional newline. It will look like this in the output HTML:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cwCentre&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;52.741865&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;8.772812&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/cozy-cottage/_site/assets/images/marker.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;secondaryMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/cozy-cottage/_site/assets/images/marker-2.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mainBrandColour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#398A8D&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Cozy Cottage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;p&amp;gt;Test content&amp;lt;/p&amp;gt;
&quot;&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;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cwCentre&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;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will trigger an error, due to the bogus character at the end of the line.&lt;/p&gt;

&lt;p&gt;You’ll see the error: &lt;strong&gt;‘Uncaught SyntaxError: Unexpected token ILLEGAL’&lt;/strong&gt; in the browser console and the script will fail.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;strip_newlines&lt;/code&gt; filter sorts this out.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.shopify.com/themes/liquid-documentation/filters/string-filters#strip_newlinesS&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;strip_newlines&lt;/code&gt; liquid tag documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/17754312/how-to-suppress-blank-line-in-jekyll&quot;&gt;Suppress blank line in Jekyll&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 21 Nov 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/11/js-variables-in-markdown-includes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/11/js-variables-in-markdown-includes/</guid>
      </item>
      
    
      
      <item>
        <title>Using rsync to Copy Incremental Backups</title>
        <description>&lt;p&gt;Copy a directory comprised of incremental backup to a separate hard disk.&lt;/p&gt;

&lt;p&gt;When an &lt;a href=&quot;/2015/06/incremental-backup-on-server/&quot;&gt;incremental backup&lt;/a&gt; makes use of &lt;a href=&quot;http://www.linfo.org/hard_link.html&quot;&gt;hardlinks&lt;/a&gt;, these need to be preserved when copying the backup directory. Otherwise, all files are copied individually, taking up a lot more space on the destination directory.&lt;/p&gt;

&lt;p class=&quot;emphasis-block&quot;&gt;&lt;span class=&quot;h3&quot;&gt;&lt;i class=&quot;icon-flash&quot;&gt;&lt;/i&gt;File Format&lt;/span&gt;&lt;br /&gt;If copying to an external drive, it should be formatted to an ext3 or ext4 filesystem. FAT(32) formatting won’t work - it doesn’t support permission &amp;amp; ownership data&lt;/p&gt;

&lt;h2 id=&quot;maintain-hardlinks&quot;&gt;Maintain Hardlinks&lt;/h2&gt;

&lt;p&gt;When rsync’ing with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-a&lt;/code&gt; option, hardlinks are NOT automatically preserved:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that -a does not preserve hardlinks, because finding multiply-linked files is expensive. You must separately specify -H.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync Man page&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hardlinks are generally a critical element of &lt;a href=&quot;/2015/06/incremental-backup-on-server/&quot;&gt;incremental backups&lt;/a&gt;. Hardlinks allow multiple directory/file entries to be associated with a single inode. If you do not include the rsync &lt;code class=&quot;highlighter-rouge&quot;&gt;-H&lt;/code&gt; argument, when copying a set of incrementally backed-up directories rsync would copy files in their entirety. This would lose the space saving benefits of the hardlinked incremental backup.&lt;/p&gt;

&lt;h2 id=&quot;rsync-command&quot;&gt;rsync Command&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rsync -az --exclude&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'*.zip'&lt;/span&gt; -H --progress /source-drive/name /destination-drive&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-a&lt;/code&gt; Archive mode; recursive, copy symlinks as symlinks, preserve permissions, preserve modification times, preserve group, preserve owner, preserve special &amp;amp; device files.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-z&lt;/code&gt; Compress the file data being transferred&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;--exclude='*.zip'&lt;/code&gt; do not transfer files with a &lt;code class=&quot;highlighter-rouge&quot;&gt;.zip&lt;/code&gt; extension&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-H&lt;/code&gt; Preserve hardlinks&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;--progress&lt;/code&gt; print info about the transfer (for the terminally bored, but at least you can see it’s doing something)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that the lack of a trailing slash on the source directory will result in this directory being created in the destination directory (if it doesn’t already exist).&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.evbackup.com/support-commonly-used-rsync-arguments/&quot;&gt;Common rsync arguments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync Man page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 31 Oct 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/10/backup-rsync-between-devices/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/10/backup-rsync-between-devices/</guid>
      </item>
      
    
      
      <item>
        <title>Relative File Paths in PHP</title>
        <description>&lt;p&gt;Relative file paths are used when including or requiring files.&lt;/p&gt;

&lt;p&gt;In the context of a WordPress plugin or theme, you may be referencing a file that is in a ‘parallel’ directory.&lt;/p&gt;

&lt;p&gt;In the example below, the plugin root directory is referenced by multiple use of the PHP &lt;code class=&quot;highlighter-rouge&quot;&gt;dirname()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;dirname()&lt;/code&gt; returns a parent directory’s path.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Target file: &lt;code class=&quot;highlighter-rouge&quot;&gt;/includes/class-staff-area-access.php&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Originating file: &lt;code class=&quot;highlighter-rouge&quot;&gt;/admin/partials/access-check.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// function is called in a subdirectory nested two deep from the project root
plugin_dir_path( dirname ( dirname( __FILE__ ) ) ) . 'includes/class-staff-area-access.php' ;

// This achieves the same result, using the __DIR__ magic constant:
echo plugin_dir_path( dirname( __DIR__ ) ) . 'includes/class-staff-area-access.php' ;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notes on the PHP Magic constants:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;__FILE__&lt;/code&gt; - the full path and filename of the file (with symlinks resolved)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;__DIR__&lt;/code&gt; - the directory of the file&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dirname-in-php-7&quot;&gt;dirname() in PHP 7&lt;/h2&gt;
&lt;p&gt;In PHP 7, &lt;code class=&quot;highlighter-rouge&quot;&gt;dirname()&lt;/code&gt; will accept an optional &lt;strong&gt;levels&lt;/strong&gt; parameter. This means the above code could be replaced with:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// PHP 7:
echo dirname( __DIR__ , 2 ) . '/includes/class-staff-area-access.php' ;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;wordpress-function-plugindirpath&quot;&gt;WordPress Function: plugin_dir_path()&lt;/h2&gt;
&lt;p&gt;The WordPress function &lt;code class=&quot;highlighter-rouge&quot;&gt;plugin_dir_path()&lt;/code&gt; gets the filesystem directory path for the file passed in. It includes a trailing slash.&lt;/p&gt;

&lt;p&gt;The function is a wrapper for &lt;code class=&quot;highlighter-rouge&quot;&gt;trailingslashit( dirname( $file ) )&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Function_Reference/plugin_dir_path&quot;&gt;WP Codex plugin_dir_path()&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://php.net/manual/en/function.dirname.php&quot;&gt;PHP dirname() PHP Docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/6511020/get-2-levels-up-from-dirname-file&quot;&gt;SO Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 06 Oct 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/10/relative-file-paths-php/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/10/relative-file-paths-php/</guid>
      </item>
      
    
      
      <item>
        <title>Control File Access by IP in Apache 2.4</title>
        <description>&lt;p&gt;Denying access to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-login.php&lt;/code&gt; for all but a set of whitelisted IP can be a good way of enhancing site security - provided that the client has a fixed IP address.&lt;/p&gt;

&lt;p&gt;We typically add such access controls within a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file in the document root of a project, leaving login access for our own IP address and that of the site owner.&lt;/p&gt;

&lt;p&gt;You might occasionally need to temporarily whitelist an additional IP address, but this is easy to do.&lt;/p&gt;

&lt;p&gt;Restricting access by IP address is no substitute for a proper username/password policy - but it may be a useful additional layer, since would-be attackers don’t even get a chance to knock on the door.&lt;/p&gt;

&lt;p&gt;Under Apache 2.2, you could use these directives within a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Whitelisted IP access for wp-login.php&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; wp-login.php&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;order&lt;/span&gt; deny,allow
&lt;span class=&quot;nc&quot;&gt;deny&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; all

&lt;span class=&quot;c&quot;&gt;# whitelist Your First IP address&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;allow&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; xxx.xxx.xxx.xxx
&lt;span class=&quot;c&quot;&gt;# whitelist Your Second IP Address&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;allow&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; xxx.xxx.xxx.xxx
&lt;span class=&quot;c&quot;&gt;# whitelist Your Third IP Address&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;allow&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; xxx.xxx.xxx.xxx

&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Protect specified files from direct access&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;^(wp-config\.php|php\.ini|php5\.ini|install\.php|php\.info|readme\.html|bb-config\.php|\.htaccess|\.htpasswd|readme\.txt|timthumb\.php|error_log|error\.log|PHP_errors\.log|\.svn)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Deny&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; all
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;FilesMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Whilst the &lt;code class=&quot;highlighter-rouge&quot;&gt;Allow&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;Order&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;Deny&lt;/code&gt; directives still work in Apache 2.4, they are deprecated:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Allow, Deny, and Order directives, provided by mod_access_compat, are deprecated and will go away in a future version. You should avoid using them, and avoid outdated tutorials recommending their use.&lt;/p&gt;

  &lt;p&gt;-&lt;a href=&quot;http://httpd.apache.org/docs/2.4/howto/access.html&quot;&gt;Apache 2.4 Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, there is not a lot of literature on how to properly set up such restrictions on Apache 2.4 - without relying on &lt;code class=&quot;highlighter-rouge&quot;&gt;mod_access_compat&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;deny-access-completely&quot;&gt;Deny Access Completely&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;Apache 2.2&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apacheconf&quot; data-lang=&quot;apacheconf&quot;&gt;Order deny,allow
Deny from all&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In &lt;strong&gt;Apache 2.4&lt;/strong&gt; this becomes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; all denied&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;restrict-access-by-ip-address-comparison-of-apache-22-and-24&quot;&gt;Restrict Access by IP address: Comparison of Apache 2.2 and 2.4&lt;/h2&gt;

&lt;p&gt;Allow from a particular IP in &lt;strong&gt;Apache 2.2&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Order&lt;/span&gt; Deny,Allow
&lt;span class=&quot;nc&quot;&gt;Deny&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; all
&lt;span class=&quot;nc&quot;&gt;Allow&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;from&lt;/span&gt; xxx.xxx.xxx.xxx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Allow from a particular IP in &lt;strong&gt;Apache 2.4&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip xxx.xxx.xxx.xxx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;tldr-restrict-access-apache-24&quot;&gt;TL;DR Restrict Access Apache 2.4&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Restrict access to WordPress login page by IP&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See: http://httpd.apache.org/docs/2.4/mod/core.html#files&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==============================================================================&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; &quot;wp-login.php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;nc&quot;&gt;Require&lt;/span&gt; ip 123.123.123.123
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you have full access to Apache config on your server, you can enable these directives for all virtual hosts by adding them to the Apache config file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/conf-enabled/security.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.bravi.org/?p=1191&quot;&gt;One of the rare useful guides on access control in Apache 2.2 vs 2.4&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/howto/auth.html&quot;&gt;Apache 2.4. docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require&quot;&gt;Apache 2.4 Require directive&lt;/a&gt; - maybe it’s because it’s Friday night after a long week, but this page made my brain hurt…&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/mod/mod_authz_host.html&quot;&gt;A better resource on the Require directive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/mod/core.html#files&quot;&gt;&amp;lt;Files&amp;gt; Directive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/mod/core.html#filesmatch&quot;&gt;&amp;lt;FilesMatch&amp;gt; Directive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://httpd.apache.org/docs/2.4/mod/core.html#options&quot;&gt;Options directive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 01 Oct 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/10/restrict-access-by-ip-apache-2-4/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/10/restrict-access-by-ip-apache-2-4/</guid>
      </item>
      
    
      
      <item>
        <title>Page Sections in Jekyll</title>
        <description>&lt;p&gt;The objective is to set up a services page that will have multiple sections. Each section will contain a block of HTML and an image.&lt;/p&gt;

&lt;p&gt;It should be easy to edit section content in obvious markdown files, and we should avoid duplication as much as possible.&lt;/p&gt;

&lt;h2 id=&quot;data-driven-sections&quot;&gt;Data Driven Sections&lt;/h2&gt;
&lt;p&gt;Jekyll can read data files in either &lt;code class=&quot;highlighter-rouge&quot;&gt;YAML&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;JSON&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;CSV&lt;/code&gt; format. Data is loaded from files with these formats located in the &lt;code class=&quot;highlighter-rouge&quot;&gt;_data&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Data files allow us to specify files to be used as includes or images, and help avoid repetition in templates. You just set up the data file correctly, and edit the (content) source files without touching the template.&lt;/p&gt;

&lt;h2 id=&quot;data-setup&quot;&gt;Data Setup&lt;/h2&gt;
&lt;p&gt;Though I have tinkered with using &lt;code class=&quot;highlighter-rouge&quot;&gt;CSV&lt;/code&gt; format data files (to make it easier to harvest user generated content), I prefer the &lt;code class=&quot;highlighter-rouge&quot;&gt;YAML&lt;/code&gt; format - basically because I prefer how the data looks in a text editor. If you do use &lt;code class=&quot;highlighter-rouge&quot;&gt;CSV&lt;/code&gt;, &lt;strong&gt;you need to include a header row&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For this post, we’ll focus on the &lt;code class=&quot;highlighter-rouge&quot;&gt;YAML&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;Create a new data file: &lt;code class=&quot;highlighter-rouge&quot;&gt;/_data/service-sections.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enter data, being careful with whitespace and tabs:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Pleated&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Blinds&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;domestic/pleated-blinds.md&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;assets/images/medium-images/pleated-blinds.jpg&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image-title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;service-category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;domestic&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Roller&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Blinds&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;commercial/roller-blinds.md&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;assets/images/medium-images/Rollerblinds.jpg&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image-title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;service-category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;commercial&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Plantation&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Shutters&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;domestic/plantation-shutters.md&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;assets/images/medium-images/plantation-shutters.jpg&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image-title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;service-category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;domestic&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Vertical&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Blinds&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;domestic/vertical-blinds.md&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;assets/images/medium-images/vertical-blinds.jpg&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image-title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;service-category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;domestic&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Roman&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Blinds&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;domestic/roman-blinds.md&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;assets/images/medium-images/roman-blinds.jpg&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;image-title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;service-category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;domestic&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case, the data file serves as a way of referencing the files that contain the content.&lt;/p&gt;

&lt;p&gt;Under each &lt;code class=&quot;highlighter-rouge&quot;&gt;YAML&lt;/code&gt; block, the &lt;code class=&quot;highlighter-rouge&quot;&gt;description&lt;/code&gt; field is a path to a markdown include. I’ve tried to make this as logical as possible, by having an appropriate directory structure within the &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes&lt;/code&gt; directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes/services/service-name/content-file.md&lt;/code&gt;… so if you want to add content to the section on “Roller Blinds” on the “Commercial” services page, you need to edit &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes/services/commercial/roller-blinds.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a similar way, we can reference images, titles and other data for each section.&lt;/p&gt;

&lt;h2 id=&quot;the-html-include&quot;&gt;The HTML Include&lt;/h2&gt;
&lt;p&gt;The section data are looped through within a HTML include, which is in turn inserted in the &lt;code class=&quot;highlighter-rouge&quot;&gt;service_page&lt;/code&gt; template. IN this case, the include is &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes/layouts/services-sections.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The include does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sets up a for loop that goes through each data block in the specified data file.&lt;/li&gt;
  &lt;li&gt;Makes section display conditional&lt;/li&gt;
  &lt;li&gt;Builds variable content into the correct HTML markup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sections displayed must have a service-category that corresponds to the page service-category (which needs to be set in the page front-matter). This allows us to easily define section content for different service pages from within the data file.&lt;/p&gt;

&lt;p&gt;For example, this is &lt;code class=&quot;highlighter-rouge&quot;&gt;_includes/layouts/services-sections.html&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{% for section in site.data.service-sections %}
  {% if page.service-category == section.service-category %}
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row section&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-sm-6&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;{{ section.title }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;&amp;lt;!--
        To properly render markdown includes as HTML, the include tag must be
        captured as a string, and this must be passed to the `markdownify` filter.
        --&amp;gt;&lt;/span&gt;
        {% capture section_description %}{% include services/{{ section.description }} %}{% endcapture %}
        {{ section_description | markdownify }}

        &lt;span class=&quot;c&quot;&gt;&amp;lt;!--
        The following will not parse the markdown include - it won't be properly
        rendered into HTML and will display as the original markdown.
        --&amp;gt;&lt;/span&gt;
        {% comment %}
        {% include services/{{ section.description }} %}      
        {% endcomment %}
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-sm-5 col-sm-offset-1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;thumbnail&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!--
          Build the image markup for this section. If an image-caption has been
          defined, display it.
          --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.baseurl }}/{{ section.image }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ section.title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ section.title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;img-responsive&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          {% if nil != service.img-caption %}
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;img-caption&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;{{ service.img-caption }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          {% endif %}
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
  {% endif %}
{% endfor %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is included within the &lt;code class=&quot;highlighter-rouge&quot;&gt;index.html&lt;/code&gt; page of each service. For example, &lt;code class=&quot;highlighter-rouge&quot;&gt;domestic/index.html&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;indexhtml&quot;&gt;index.html&lt;/h2&gt;
&lt;p&gt;The service page (&lt;code class=&quot;highlighter-rouge&quot;&gt;service-name/index.html&lt;/code&gt;) front matter sets the page title, meta description etc. It also sets the service-category, which is used in the &lt;code class=&quot;highlighter-rouge&quot;&gt;layouts/services-sections.html&lt;/code&gt; include to build the correct section content. For example, this is &lt;code class=&quot;highlighter-rouge&quot;&gt;domestic/index.html&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;---
layout: service-page
title: Domestic Blinds &lt;span class=&quot;err&quot;&gt;&amp;amp;&lt;/span&gt; Shutters
group: navigation
title: Domestic Blinds and Shutters
description: Quality domestic blinds &lt;span class=&quot;err&quot;&gt;&amp;amp;&lt;/span&gt; shutters in Limerick, Clare, Tipperary
service-category: domestic
intro-content: domestic/domestic.md
intro-image: assets/images/logo.png
intro-image-title: &quot;Irish Blinds &lt;span class=&quot;err&quot;&gt;&amp;amp;&lt;/span&gt; Shutters&quot;
extra-content: domestic/domestic-col-2.md
---
{% capture service_intro %}
  {% include services/{{ page.intro-content }} %}
{% endcapture %}
{% capture service_extra %}
  {% include services/{{ page.extra-content }} %}
{% endcapture %}
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-md-6&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;header&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;post-header&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ page.title }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
      {{ service_intro | markdownify }}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-md-5 col-md-offset-1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;thumbnail hidden-sm&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ site.baseurl }}/{{ page.intro-image }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ page.intro-image-title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{ page.intro-image-title }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;img-responsive&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    {% if page.col-2-content != empty %}
      {{ service_extra | markdownify }}
    {% endif %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Include the service sections here. --&amp;gt;&lt;/span&gt;
{% include layouts/services-sections.html %}
&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- End service sections --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-md-6&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Contact Us Now to Get Started&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    {% include general/body-phone.html %}
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Did we achieve the objectives of data-driven page sections? Kind of. Overall it’s a pretty good solution - it means that we can manage site content in a fairly straightforward way.&lt;/p&gt;

&lt;p&gt;There are still more edit points than I’d like, and I don’t like the way that the service sections are bunched up in a single data file.&lt;/p&gt;

&lt;p&gt;I’d prefer to be able to create separate data files for each page category - but I had trouble creating a dynamic reference to the data file whilst setting up the for loop. I still have a lot to learn about Jekyll (and Ruby), so it could well be that I’m missing something obvious.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/datafiles/&quot;&gt;Jekyll Data Files&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Interesting article on &lt;a href=&quot;http://www.tournemille.com/blog/How-to-create-data-driven-navigation-in-Jekyll/&quot;&gt;dynamic navigation in Jekyll&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jekyll/jekyll/issues/1303&quot;&gt;Reference to markdown includes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 28 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/jekyll-page-sections/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/jekyll-page-sections/</guid>
      </item>
      
    
      
      <item>
        <title>Find and Replace Filenames</title>
        <description>&lt;p&gt;This might be needed when starting a project by cloning a scaffold boilerplate from Github (e.g. the WordPress boilerplate plugin).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TODO&lt;/strong&gt; Build a BASH script to scaffold projects with automatic renaming of files.&lt;/p&gt;

&lt;h2 id=&quot;rename-filenames-in-wp-plugin-boilerplate&quot;&gt;Rename filenames in WP Plugin Boilerplate&lt;/h2&gt;
&lt;p&gt;Rename files and directories recursively. Run from the project root:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Test run&lt;/span&gt;
find . -iname &lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt; -exec rename -n &lt;span class=&quot;s1&quot;&gt;'s/plugin-name/carawebs-codename/g'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{}'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Apply the Rename, verbose output lists changes&lt;/span&gt;
find . -iname &lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt; -exec rename -v &lt;span class=&quot;s1&quot;&gt;'s/plugin-name/carawebs-codename/g'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{}'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

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

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; runs the find command recursively in the current directory - in this case it finds all files &amp;amp; directories&lt;/li&gt;
  &lt;li&gt;The -exec argument executes rename for every matching file found - all files.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;'{}'&lt;/code&gt; is replaced with the path name of the file.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;\;&lt;/code&gt; marks the end of the exec expression.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;-n&lt;/code&gt; option on rename runs the command in “no act” mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The substitution takes the form &lt;code class=&quot;highlighter-rouge&quot;&gt;s/target/replacement/[gi]&lt;/code&gt;, where:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;target&lt;/code&gt; is the string to be replaced&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;replacement&lt;/code&gt; is the replacing string&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;g&lt;/code&gt; option is for ‘global’ action - all instances are replaced.&lt;/p&gt;

&lt;p&gt;An &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; denotes a case insensitive rename.&lt;/p&gt;

&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;/h2&gt;
&lt;p&gt;Find .jpg files with the string ‘holiday’ in the filename, replacing this with ‘vacation’:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;find . -type f -name &lt;span class=&quot;s1&quot;&gt;'*.jpg'&lt;/span&gt; | rename &lt;span class=&quot;s1&quot;&gt;'s/holiday/vacation/'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux&quot;&gt;SO Question: Recursive renaming in linux&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.computerhope.com/unix/rename.htm&quot;&gt;Unix rename&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 27 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/find-and-replace-filenames/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/find-and-replace-filenames/</guid>
      </item>
      
    
      
      <item>
        <title>rsync Notes- Push a WP Plugin</title>
        <description>&lt;p&gt;Use rsync to push a plugin from a local development machine to a remote server.&lt;/p&gt;

&lt;h2 id=&quot;sync-a-single-wp-plugin&quot;&gt;Sync a Single WP Plugin&lt;/h2&gt;

&lt;p&gt;Trailing slash or not? That is the question…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rsync -raz -e &lt;span class=&quot;s1&quot;&gt;'ssh -p 1234'&lt;/span&gt; --progress /var/www/localsite/wp-content/plugins/plugin-name user@X.X.X.X:/var/www/sitename.com/public_html/wp-content/plugins&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;No trailing slash&lt;/strong&gt; on source path: rsync will create the last directory of the path before copying content. In the case above, you’d end up with &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/sitename.com/public_html/wp-content/plugins/plugin-name/*files.*&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Append a trailing slash&lt;/strong&gt; - rsync will only copy the contents (subdirectories and files) of the source directory directly to the target - &lt;strong&gt;Not&lt;/strong&gt; the directory itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m always forgetting this - it seems counter-intuitive!&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://devblog.virtage.com/2013/01/to-trailing-slash-or-not-to-trailing-slash-to-rsync-path/&quot;&gt;http://devblog.virtage.com/2013/01/to-trailing-slash-or-not-to-trailing-slash-to-rsync-path/&lt;/a&gt;
&lt;a href=&quot;http://qdosmsq.dunbar-it.co.uk/blog/2013/02/rsync-to-slash-or-not-to-slash/&quot;&gt;http://qdosmsq.dunbar-it.co.uk/blog/2013/02/rsync-to-slash-or-not-to-slash/&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 22 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/rsync-notes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/rsync-notes/</guid>
      </item>
      
    
      
      <item>
        <title>Finding Files in git History</title>
        <description>&lt;p&gt;You may need to find a file in your commit history - perhaps the file was deleted, and you need the functionality that it contained.&lt;/p&gt;

&lt;h2 id=&quot;show-commits-where-the-file-changed&quot;&gt;Show Commits where the File Changed&lt;/h2&gt;
&lt;p&gt;This will show commits where the file changed, even if the file has been deleted:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git log -- /path/to/target/file&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will provide a log of commits that involved the specified file changing.&lt;/p&gt;

&lt;h2 id=&quot;view-the-commit-associated-with-file-deletion&quot;&gt;View the Commit Associated with File Deletion&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git log -1 -- /path/to/target/file&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This shows the last commit that contained the file. You could specify a different number to see the last x commits.&lt;/p&gt;

&lt;h2 id=&quot;view-the-relevant-commit&quot;&gt;View the Relevant Commit&lt;/h2&gt;
&lt;p&gt;Once you have determined the commit reference, you can view the file by selecting the relevant in an online repo.&lt;/p&gt;

&lt;p&gt;You could also check out the commit:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git checkout d33ffc9&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you checkout the commit, you can view and edit files without affecting the current state of the project. You need to checkout your working branch (usually ‘master’) to go back to work.&lt;/p&gt;

&lt;p&gt;It’s usually enough to grab the commit reference and view this in the online repo (Bitbucket or Github).&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.vogella.com/tutorials/Git/article.html#retrievefiles_finddeletedfile&quot;&gt;Comprehensive Git Tutorial by Lars Vogel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 21 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/finding-files-git/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/finding-files-git/</guid>
      </item>
      
    
      
      <item>
        <title>Bootstrap 4 Navbar</title>
        <description>&lt;p&gt;There are quite a few changes in Bootstrap 4 (it’s SASS rather than LESS for a start!).&lt;/p&gt;

&lt;p&gt;One of these changes is the navbar. Here’s the markup for the basic navbar on this page:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;header&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;top&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Web Development Notes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Various Cheat Sheets and Resources by David Egan/Carawebs.&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;section&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;main-nav&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;nav&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navbar&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav navbar-nav&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://carawebs.com&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Carawebs Main Site&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Dev-Notes Home&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/linux/&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Linux&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;          
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/wordpress/&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;WordPress&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;         
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/tools/&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Tools&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;          
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/contact&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;          
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;new-in-bootstrap-4&quot;&gt;New in Bootstrap 4&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nav-item&lt;/code&gt; class on the li elements&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nav-link&lt;/code&gt; class on the nav links themselves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m still digging in to Bootstrap - I intend to add more navbar fragments as I build them.&lt;/p&gt;

&lt;p&gt;One thing to note is that the navbar doesn’t yet collapse at mobile views.&lt;/p&gt;

&lt;h2 id=&quot;liquidjekyll-markup&quot;&gt;Liquid/Jekyll Markup&lt;/h2&gt;
&lt;p&gt;This is a Jekyll site, so I build the navbar shown above like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;header&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;top&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{site.baseurl}}/&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;{{ site.name }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;{{ site.description }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;section&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;main-nav&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;nav&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;navbar&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav navbar-nav&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://carawebs.com&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Carawebs Main Site&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          {% for node in site.navigable-pages %}
          {% if page.url == node.url/ %}
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{site.baseurl}}{{ node.url }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link active&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;{{ node.title }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          {% else %}
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nav-item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{{site.baseurl}}{{ node.url }}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn nav-link&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;{{ node.title }}&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          {% endif %}
          {% endfor %}
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Jekyll will then render the final HTML as shown above.&lt;/p&gt;
</description>
        <pubDate>Mon, 21 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/bootstrap-4-navbar/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/bootstrap-4-navbar/</guid>
      </item>
      
    
      
      <item>
        <title>Install a Dev Branch with Bower</title>
        <description>&lt;p&gt;I decided to try out the Bootstrap 4 CSS framework on this website. It’s still in Alpha, and not recommended for production sites.&lt;/p&gt;

&lt;p&gt;I wanted to install Bootstrap by means of Bower. You normally install via Bower by moving to the project root directory and entering:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bower install &amp;lt;package&amp;gt; --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the case of Bootstrap, you’d enter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bower install bootstrap --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The Bootstrap assets would be downloaded and automatically added to a &lt;code class=&quot;highlighter-rouge&quot;&gt;bower_components&lt;/code&gt; directory in your project.&lt;/p&gt;

&lt;h2 id=&quot;packagejson&quot;&gt;package.json&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;--save-dev&lt;/code&gt; flag adds the package as a project dependency in your &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; file - so running &lt;code class=&quot;highlighter-rouge&quot;&gt;bower install&lt;/code&gt; against your project will install the package you’ve just added.&lt;/p&gt;

&lt;p&gt;If you don’t have a &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; file, you can run &lt;code class=&quot;highlighter-rouge&quot;&gt;bower init&lt;/code&gt; to generate one.&lt;/p&gt;

&lt;p&gt;This method fetches the latest stable version, so it’s no good for fetching the Bootstrap 4 development branch.&lt;/p&gt;

&lt;h2 id=&quot;install-endpoints&quot;&gt;Install endpoints&lt;/h2&gt;
&lt;p&gt;Fortunately, there are a range of endpoints for the &lt;code class=&quot;highlighter-rouge&quot;&gt;install&lt;/code&gt; command. You can install a package version - a valid range, commit or branch by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;bower install &amp;lt;package&amp;gt;#&amp;lt;version&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;package&amp;gt;&lt;/code&gt; refers to a package URL, physical location or Bower registry name.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;version&amp;gt;&lt;/code&gt; can be a:
    &lt;ul&gt;
      &lt;li&gt;semver version (#1.2.3)&lt;/li&gt;
      &lt;li&gt;version range&lt;/li&gt;
      &lt;li&gt;git tag&lt;/li&gt;
      &lt;li&gt;git commit SHA&lt;/li&gt;
      &lt;li&gt;git branch&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;install-bootstrap-4-dev-branch&quot;&gt;Install Bootstrap 4 Dev Branch&lt;/h2&gt;
&lt;p&gt;Determine the relevant branch (via GitHub) and add it as an endpoint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;bower install bootstrap#v4-dev --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://bower.io/docs/api/#install/&quot;&gt;Bower Install&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 20 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/bower-for-dev-branch/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/bower-for-dev-branch/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Error Logging</title>
        <description>&lt;p&gt;In general, error logging should be enabled in the development environment and disabled in production environments.&lt;/p&gt;

&lt;p&gt;To enable WordPress error reporting to the browser, and to enable error logging to file, add the following lines to &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// Enable error reporting output to browser. Default value is false.
define( 'WP_DEBUG', true );

// log errors to `/wp-content/debug.log`. Useful when debugging code that does not output to browser.
define('WP_DEBUG_LOG', true);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;Enabling WP_DEBUG will cause all PHP errors, notices and warnings to be displayed. This is likely to modify the default behavior of PHP which only displays fatal errors and/or shows a white screen of death when errors are reached.&lt;/p&gt;

  &lt;p&gt;Showing all PHP notices and warnings often results in error messages for things that don’t seem broken, but do not follow proper data validation conventions inside PHP. These warnings are easy to fix once the relevant code has been identified, and the resulting code is almost always more bug-resistant and easier to maintain.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://codex.wordpress.org/Debugging_in_WordPress&quot;&gt;WordPress Codex&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;browser-debugging&quot;&gt;Browser Debugging&lt;/h2&gt;
&lt;p&gt;Enabling WP_DEBUG provides useful error messages rather than the “white screen of death”.&lt;/p&gt;

&lt;p&gt;Even when code is not broken, debugging output will highlight deprecated WordPress functions and other problems.&lt;/p&gt;

&lt;h2 id=&quot;logging&quot;&gt;Logging&lt;/h2&gt;
&lt;p&gt;The WP_DEBUG_LOG option is very useful for situations that do not involve output to the browser - for example AJAX requests. It is also useful when debugging classes or functions that pass data to other scripts.&lt;/p&gt;

&lt;p&gt;You can make code write to the debug log using the PHP &lt;code class=&quot;highlighter-rouge&quot;&gt;error_log()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;For example, in the following code fragment, taken from a class method, the &lt;code class=&quot;highlighter-rouge&quot;&gt;$column_name&lt;/code&gt; variable is output to the error log - so that we can check we’re getting the right values at this point in the programme:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Headings
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$wpdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;DESC &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table_name&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;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column_name&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;c1&quot;&gt;// output $column_name to the error log
&lt;/span&gt;      &lt;span class=&quot;nb&quot;&gt;error_log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$csv_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$csv_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;monitoring-the-log-file&quot;&gt;Monitoring the Log File&lt;/h2&gt;
&lt;p&gt;The log file must be owned by the server process - in the case of Ubuntu, this is ‘www-data’.&lt;/p&gt;

&lt;p&gt;I often &lt;code class=&quot;highlighter-rouge&quot;&gt;chown&lt;/code&gt; ownership back and forth for various reasons - so wrong ownership of debug.log often trips me up. When developing a theme or plugin, it’s probably best to create an alias giving ownership of just the theme or plugin directory to &lt;code class=&quot;highlighter-rouge&quot;&gt;$USER&lt;/code&gt; - leaving the rest of the development site owned by &lt;code class=&quot;highlighter-rouge&quot;&gt;www-data&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It can be useful to view the debug.log in realtime. The &lt;code class=&quot;highlighter-rouge&quot;&gt;tail&lt;/code&gt; utility with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-f&lt;/code&gt; (follow) option is good for this.&lt;/p&gt;

&lt;p&gt;Open a terminal and add the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tail -f /path/to/debug.log&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This outputs the last 10 lines of &lt;code class=&quot;highlighter-rouge&quot;&gt;debug.log&lt;/code&gt;, and the output data will be appended if the file grows - so you’ll have a realtime monitor of the debug log in your terminal. If you need more lines, append the &lt;code class=&quot;highlighter-rouge&quot;&gt;-n&lt;/code&gt; flag to the &lt;code class=&quot;highlighter-rouge&quot;&gt;tail&lt;/code&gt; command. To output the last 50 lines of the log file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tail -f /path/to/debug.log -n 50&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Alternatively, open &lt;code class=&quot;highlighter-rouge&quot;&gt;debug.log&lt;/code&gt; in a text editor (e.g. gedit). After running your code, activate the editor window - under Ubuntu at least you’dd see a “changed on disk” notification - relaoding the file will show the new error output.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Debugging_in_WordPress&quot;&gt;Debugging in WordPress: Codex&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 15 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/wordpress-error-logging/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/wordpress-error-logging/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Filter Hooks</title>
        <description>&lt;p&gt;Filters can operate on content snippets or on arrays.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Filters are the hooks that WordPress launches to modify text of various types before adding it to the database or sending it to the browser screen. Your plugin can specify that one or more of its PHP functions is executed to modify specific types of text at these times, using the Filter API.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;http://codex.wordpress.org/Plugin_API&quot;&gt;WordPress Codex&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To set up content for filtering, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;apply_filters()&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;apply_filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$var&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-the-hook&quot;&gt;Create the Hook&lt;/h2&gt;
&lt;p&gt;Apply filters attached to ‘custom_content_filter’ to $content. This would be typically added to a template file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;$content = apply_filters ( 'custom_content_filter', 'alert alert-info' );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-filter&quot;&gt;Create Filter&lt;/h2&gt;
&lt;p&gt;Create the filter and attach to the filter hook. Typically in custom functions file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function carawebs_wrap_content( $content, $div_class ) {

    if ( 'blockquote' == $wrap_tag ) {

        return &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;blockquote&amp;gt;&lt;/span&gt;&quot; . $content . &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/blockquote&amp;gt;&lt;/span&gt;&quot;;

    } else {

        return &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'$div_class'&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&quot; . $content . &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&quot;;

    }

}

// Filter the content passed in from 'custom_content_filter' with the
// specified callback function - in this case, 'carawebs_wrap_content'.

add_filter ( 'custom_content_filter', 'carawebs_wrap_content' );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;wordpress-filters&quot;&gt;WordPress Filters&lt;/h2&gt;
&lt;p&gt;There are many built-in WordPress filters. For example, ‘the_content’ filters content after database retrieval and before printing to the screen. To use this filter, it’s simply a matter of passing the content. This can be very useful when fetching post content outside the loop using &lt;code class=&quot;highlighter-rouge&quot;&gt;get_the_content()&lt;/code&gt; - which returns unfiltered content.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;$raw_content = get_the_content( $current_ID );
$filtered_content = apply_filters( 'the_content', $raw_content );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Filter functions can be added using the &lt;code class=&quot;highlighter-rouge&quot;&gt;add_filter()&lt;/code&gt; function. For example, this function prepends a post thumbnail to the $content passed in to the ‘the_content’ filter - which is usually the post content:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// From WP Codex.
// @see: https://codex.wordpress.org/Plugin_API/Filter_Reference/the_content

add_filter( 'the_content', 'featured_image_before_content' );

 function featured_image_before_content( $content ) {

    if ( is_singular('post') &lt;span class=&quot;err&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; has_post_thumbnail()) {

        $thumbnail = get_the_post_thumbnail();
        $content = $thumbnail . $content;

		}

    return $content;
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;From &lt;a href=&quot;https://codex.wordpress.org/Plugin_API/Filter_Reference/the_content&quot;&gt;WP Codex&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://dev.themeblvd.com/tutorial/filters/&quot;&gt;Good decription of Filters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 02 Sep 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/09/wordpress-filter-hooks/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/09/wordpress-filter-hooks/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Action Hooks</title>
        <description>&lt;p&gt;Placing &lt;code class=&quot;highlighter-rouge&quot;&gt;do_action( $tag, $arg )&lt;/code&gt; within a theme or plugin allows all functions attached to the action hook $tag to be invoked at this specific point.&lt;/p&gt;

&lt;p&gt;A callback function is registered to the action hook by means of the &lt;code class=&quot;highlighter-rouge&quot;&gt;add_action()&lt;/code&gt; function, using the $tag defined in &lt;code class=&quot;highlighter-rouge&quot;&gt;do_action()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This enables you to create an API for a theme or plugin - callbacks can be registered for a custom action.&lt;/p&gt;

&lt;p&gt;To register a callback, use &lt;code class=&quot;highlighter-rouge&quot;&gt;add_action()&lt;/code&gt;. This will typically be in the theme custom functions, where the related $function_to_add will also be defined:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$function_to_add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$priority&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$accepted_args&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To execute the callback, use &lt;code class=&quot;highlighter-rouge&quot;&gt;do_action()&lt;/code&gt;. This will typically be in the template or layout partial - anywhere where you’d like to give developers (or yourself) the ability to hook in additional content:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;do_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arg_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arg_b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$etc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;simplest-example&quot;&gt;Simplest Example&lt;/h2&gt;
&lt;p&gt;Simple example of an action hook - allows extra content to be added by the theme.&lt;/p&gt;

&lt;p&gt;Register hook before address - added in theme template or plugin layout:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;do_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'before_address'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebs_custom_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This could also be defined as part of a function or class method like this:
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;carawebs_before_address&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;nx&quot;&gt;do_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'before_address'&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;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`carawebs_before_address()`&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;would&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;added&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We can now add HTML before the address block, by hooking to the ‘before_address’ action hook. This gives layout control to the theme, which is proper.&lt;/p&gt;

&lt;p&gt;The following code would typically be located in the theme custom functions.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;namespace Carawebs\Namespace;

function address_title() {

  echo &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;A Custom Title&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;&quot;;

}

add_action (  'before_address', 'Carawebs\Namespace\address_title', 1 );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;arguments-for-the-action-hook-callback&quot;&gt;Arguments for the Action Hook Callback&lt;/h2&gt;
&lt;p&gt;The callback function that is registered by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;add_action()&lt;/code&gt; can accept arguments. The number of arguments must agree with those defined in the corresponding &lt;code class=&quot;highlighter-rouge&quot;&gt;do_action()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This means that variables defined in the same scope as the &lt;code class=&quot;highlighter-rouge&quot;&gt;do_action()&lt;/code&gt; call can be made available to the callback registered in &lt;code class=&quot;highlighter-rouge&quot;&gt;add_action()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Within the template (or better within a function invoked from the template):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;$i = 1;

foreach( $people as $person ){

  // Pass $i as an argument to do_action
  echo do_action( 'carawebs_before_person', $i );
  echo $person['name'] . &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;br&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&quot;;
  echo $person['title'] . &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;br&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&quot;;
  echo &quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;&quot;;

  $i++;

}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Within the theme custom functions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// $i is passed into the function by the do_action() setup.
function carawebs_person_intro( $i ) {

  // Echoes a numbered intro
  echo &quot;This is data for person $i&quot;;

}

// add_action( $tag, $callback, $priority, $accepted_arguments )
add_action( 'carawebs_before_person', 'carawebs_person_intro', 1, 1 );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://wpcandy.com/teaches/custom-hooks-and-pluggable-functions/#.Vd7zUXUVhBc&quot;&gt;Good description of action hooks&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Function_Reference/apply_filters&quot;&gt;Codex: apply_filters()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 20 Aug 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/08/wordpress-action-hooks/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/08/wordpress-action-hooks/</guid>
      </item>
      
    
      
      <item>
        <title>Add a .htaccess File to a Jekyll Site</title>
        <description>&lt;p&gt;Adding a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file to your document root allows fine control over access permissions.&lt;/p&gt;

&lt;p&gt;Amongst other things, &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; rules can set:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In-browser caching&lt;/li&gt;
  &lt;li&gt;Access - you could allow/disallow access from certain IP addresses or ranges&lt;/li&gt;
  &lt;li&gt;Redirects&lt;/li&gt;
  &lt;li&gt;Rewrites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also prevent modification of code over 3G on some European providers (I’ve experienced UK providers in particular totally mangling site styles).&lt;/p&gt;

&lt;p&gt;When setting up WordPress sites, we would typically lock down access to the entire admin area by IP address as a security measure. While this isn’t necessary for Jekyll sites (where there is no login), .htaccess rules can be a useful way of controlling how your site resources are cached.&lt;/p&gt;

&lt;p&gt;A proper .htaccess thereby has the potential to speed up site loading times.&lt;/p&gt;

&lt;p&gt;##.htaccess in Jekyll
By default Jekyll excludes dotfiles - but you can easily override this behaviour:&lt;/p&gt;

&lt;p&gt;In &lt;code class=&quot;highlighter-rouge&quot;&gt;config.yml&lt;/code&gt; (or &lt;code class=&quot;highlighter-rouge&quot;&gt;config_prod.yml&lt;/code&gt; if you have a production environment config file):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;s&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.htaccess'&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Jekyll will now build the &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file - which is much more convenient than editing the file on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add the .htaccess file to the root of your Jekyll project&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;sample-htaccess-for-cache-control&quot;&gt;Sample .htaccess for Cache Control&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set browser caching&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; mod_expires.c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ExpiresActive&lt;/span&gt; On
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; image/jpg &quot;access 1 year&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; image/jpeg &quot;access 1 year&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; image/gif &quot;access 1 year&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; image/png &quot;access 1 year&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; text/css &quot;access 1 month&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; text/html &quot;access 1 month&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; application/pdf &quot;access 1 month&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; text/x-javascript &quot;access 1 month&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; application/x-shockwave-flash &quot;access 1 month&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresByType&lt;/span&gt; image/x-icon &quot;access 1 year&quot;
&lt;span class=&quot;nc&quot;&gt;ExpiresDefault&lt;/span&gt; &quot;access 1 month&quot;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;IfModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# End caching block&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 05 Aug 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/08/jekyll-htaccess/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/08/jekyll-htaccess/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress File &amp; Directory Permissions</title>
        <description>&lt;p&gt;Proper permissions are necessary to ensure that a site runs correctly and is secure.&lt;/p&gt;

&lt;p&gt;Overly restrictive permissions can prevent important files from being accessed by users and/or server processes.&lt;/p&gt;

&lt;p&gt;Permissions that are too permissive constitute a security vulnerability.&lt;/p&gt;

&lt;h2 id=&quot;typical-wordpress-permissions&quot;&gt;Typical WordPress Permissions&lt;/h2&gt;

&lt;p&gt;For files, 644. For Directories, 755.&lt;/p&gt;

&lt;p&gt;If you’re viewing permissions by means of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ls&lt;/code&gt; utility on the command line:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Numerical Permissions&lt;/th&gt;
      &lt;th&gt;rwx format&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;644&lt;/td&gt;
      &lt;td&gt;-rw-r–r–&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;755&lt;/td&gt;
      &lt;td&gt;drwxr-xr-x&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;change-permissions&quot;&gt;Change Permissions&lt;/h2&gt;
&lt;p&gt;Set Directory Permissions to 755:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set directory permissions using an absolute path:&lt;/span&gt;
find /var/www/domain.com/path-to-wp -type d -exec chmod 755 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set directory permissions recursively from the current working directory:&lt;/span&gt;
find . -type d -exec chmod 755 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set File Permissions to 644:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set file permissions using an absolute path:&lt;/span&gt;
find /var/www/path-to-wp -type f -exec chmod 644 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set directory permissions recursively from the current working directory:&lt;/span&gt;
find . -type f -exec chmod 644 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;wp-configphp&quot;&gt;wp-config.php&lt;/h2&gt;
&lt;p&gt;This file contains sensitive information and should be considered separately.&lt;/p&gt;

&lt;p&gt;Access should be restricted to the owner and group only. Under Ubuntu/Apache, the following shows rational onwership/permission for &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Output of ls -la in the document root&lt;/span&gt;
-rw-rw---- 1 youruser www-data 1835 Apr 11 10:07 wp-config.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;bulk-amend-wp-configphp&quot;&gt;Bulk Amend wp-config.php&lt;/h2&gt;

&lt;p&gt;Check ownership &amp;amp; permissions on &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt; files, move into the server web root (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/html&lt;/code&gt;) and run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;find . -name &lt;span class=&quot;s1&quot;&gt;'wp-config.php'&lt;/span&gt; -exec ls -la &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To amend all &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt; files on a server, move into the server web root (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/html&lt;/code&gt;) and run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Set permissions:&lt;/span&gt;
sudo find . -name &lt;span class=&quot;s1&quot;&gt;'wp-config.php'&lt;/span&gt; -exec chmod 660 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set ownership:&lt;/span&gt;
sudo find . -name &lt;span class=&quot;s1&quot;&gt;'wp-config.php'&lt;/span&gt; -exec chown youruser:www-data &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Directories should have permissions set to 755&lt;/li&gt;
  &lt;li&gt;Files (except &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;) should have permissions set to 644&lt;/li&gt;
  &lt;li&gt;Permissions for &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt; should be set to 660&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt; should be owned by youruser:serveruser (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chown david:www-data wp-config.php&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined command to set file &amp;amp; directory permissions from the current working directory, which should be the WordPress root directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;find . -type d -exec chmod 755 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;; find . -type f -exec chmod 644 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set proper permissions/ownership on &lt;code class=&quot;highlighter-rouge&quot;&gt;wp-config.php&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo find . -name &lt;span class=&quot;s1&quot;&gt;'wp-config.php'&lt;/span&gt; -exec chmod 660 &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;
sudo find . -name &lt;span class=&quot;s1&quot;&gt;'wp-config.php'&lt;/span&gt; -exec chown youruser:www-data &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Mon, 03 Aug 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/08/wordpress-permissions/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/08/wordpress-permissions/</guid>
      </item>
      
    
      
      <item>
        <title>Using git Submodules</title>
        <description>&lt;p&gt;Submodules are a way of including third-party git repos in a project. For example, the TCPDF library might be included as a submodule in the repo of a WordPress theme.&lt;/p&gt;

&lt;h2 id=&quot;adding-a-submodule&quot;&gt;Adding a Submodule&lt;/h2&gt;
&lt;p&gt;Add an existing git repository as a submodule:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git submodule add git@github.com:WebDevStudios/CMB2.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The submodule is added by default to a directory with the same name as the repo - in this case “CMB2”.&lt;/p&gt;

&lt;h2 id=&quot;clone-with-submodules&quot;&gt;Clone With Submodules&lt;/h2&gt;
&lt;p&gt;To clone a project with submodules, use the &lt;code class=&quot;highlighter-rouge&quot;&gt;recursive&lt;/code&gt; option:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone --recursive &amp;lt;url of repo&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;retrospectively-add-submodules&quot;&gt;Retrospectively Add Submodules&lt;/h2&gt;
&lt;p&gt;You can also clone submodules as a second step - this may be necessary if you have already cloned the repo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone &amp;lt;repo&amp;gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &amp;lt;repo&amp;gt;
git submodule init
git submodule update

&lt;span class=&quot;c&quot;&gt;# To update submodule, add an extra step after running git pull&lt;/span&gt;
git pull origin master
git submodule update --recursive&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can create and switch to a new branch, which allows you to work without affecting the production code. Once happy wit changes, the branch can be merged back and deployed.&lt;/p&gt;

&lt;h2 id=&quot;deployment&quot;&gt;Deployment&lt;/h2&gt;
&lt;p&gt;If you’re using this to deploy code onto a remote server, remember that you may need an SSH key pair connection to the remote repo (e.g. GitHub).&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Tools-Submodules&quot;&gt;git guide to submodules&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/8090761/pull-using-git-including-submodule&quot;&gt;Useful Stack Overflow Answers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/generating-ssh-keys/&quot;&gt;Add SSH keys to GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 27 Jul 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/07/using-git-submodules/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/07/using-git-submodules/</guid>
      </item>
      
    
      
      <item>
        <title>Incremental Backup using rsync with Hardlinks</title>
        <description>&lt;p&gt;This method involves an incremental backup bash script that runs on a production server. The aim is to automatically build a local backup which can then be synchronised with a remote backup server.&lt;/p&gt;

&lt;h2 id=&quot;production-server-backup-user&quot;&gt;Production Server: Backup User&lt;/h2&gt;
&lt;p&gt;Create a backup user - without sudo privileges:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;adduser servernamebackup
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;production-server-source-directory&quot;&gt;Production Server: Source Directory&lt;/h2&gt;
&lt;p&gt;Create a directory called &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/source&lt;/code&gt;. This will be used as the source for the local rsync, so it forms a target for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a MySQL backup - mysqldump dumps database copies to &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/source/sql&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Symlinks to config files (in &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/source/config&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Symlinks to site files (from the Apache root directory - &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/html&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set up directories and add symlinks to &lt;code class=&quot;highlighter-rouge&quot;&gt;/source&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p /home/backupuser/source/config &lt;span class=&quot;c&quot;&gt;# make the config directories&lt;/span&gt;
sudo mkdir /home/backupuser/source/sql &lt;span class=&quot;c&quot;&gt;# target for mysqldump&lt;/span&gt;
sudo ln -s /var/www/html /home/backupuser/source &lt;span class=&quot;c&quot;&gt;# Symlink site files&lt;/span&gt;
sudo ln -s /etc/apache2 /home/backupuser/source/config &lt;span class=&quot;c&quot;&gt;# Symlink Apache config files (including vhosts setup)&lt;/span&gt;
sudo ln -s /etc/mysql /home/backupuser/source/config &lt;span class=&quot;c&quot;&gt;# Symlink MySQL config files&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;production-server-incremental-backup&quot;&gt;Production Server: Incremental Backup&lt;/h2&gt;

&lt;p&gt;Incremental backup script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Website Backup Script for SERVER&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Add this script as a cronjob to run daily. It creates an archive of incremental&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# backups, with the current date set as the name of the backup directory.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Assumes the script is run from /usr/local/sbin.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Todays date in ISO-8601 format:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DAY0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date -I&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date &lt;span class=&quot;s1&quot;&gt;'+%Y-%m-%d at %H:%M:%S'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Yesterdays date in ISO-8601 format:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DAY1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date -I -d &lt;span class=&quot;s2&quot;&gt;&quot;1 day ago&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# The source directory: this should contain a symlink to Apache doc root.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SRC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/servernamebackup/source/&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# The target directory&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TRG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/servernamebackup/backup/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DAY0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# The link destination directory&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;LNK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/servernamebackup/backup/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DAY1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Backup databases&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;XXXXXXXXXXXXXXXXXXX&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;XXXXXXXXXXXXXXXXXXXXXXXXXX&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HOST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;localhost&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DB_BACKUP_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SRC&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;sql&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Get list of databases, but not 'Database' or 'information_schema'&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DATABASES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;mysql --user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; --password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;SHOW DATABASES;&quot;&lt;/span&gt; | grep -Ev &lt;span class=&quot;s2&quot;&gt;&quot;(Database|information_schema)&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;DUMPFAIL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Remove previous dumped databases&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rm &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set up log&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Database backup report. &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt; &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/DB_LOG
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;=======================================&quot;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/DB_LOG

&lt;span class=&quot;c&quot;&gt;# Create dumps for each database&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;DB &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DATABASES&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do

  &lt;/span&gt;mysqldump -v --user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; --password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PASSWORD&lt;/span&gt; --single-transaction --log-error&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$DB&lt;/span&gt;.log --host&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOST&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DB&lt;/span&gt; &amp;gt; &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$DB&lt;/span&gt;.sql

  &lt;span class=&quot;c&quot;&gt;# Reportage - log result of mysqldump&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# ----------------------------------------------------------------------------&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -eq 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;then

    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Mysqldump created &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.sql&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/DB_LOG

  &lt;span class=&quot;k&quot;&gt;else

    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Mysqldump encountered a problem backing up &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;. Look in &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DB_BACKUP_PATH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.log for information.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class=&quot;nv&quot;&gt;$DB_BACKUP_PATH&lt;/span&gt;/DB_LOG
    &lt;span class=&quot;nv&quot;&gt;$DUMPFAIL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true

  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi

done&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# The rsync options: follow the symlinks to make a hard backup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;-avL --progress --delete --link-dest&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LNK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Execute the backup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
rsync &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$SRC&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$TRG&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Log Results&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; -gt 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# rsync Failure&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# ----------------------------------------------------------------------------&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ERROR. rsync didn't complete the nightly backup: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/server-backup.log
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;There was an error in the nightly backup for &amp;lt;servername&amp;gt;: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup Error, &amp;lt;servername&amp;gt;&quot;&lt;/span&gt; info@yourdomain.com

&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# rsync Success&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# ----------------------------------------------------------------------------&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DUMPFAIL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# rsync &amp;amp; mysqldump worked OK&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# --------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;then

      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;SUCCESS. Backup made on: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/server-backup.log

      &lt;span class=&quot;c&quot;&gt;# email the report&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: Server &amp;lt;servername&amp;gt; successfully ran a local backup.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Both rsync &amp;amp; mysqldump report success.&quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup Success, &amp;lt;servername&amp;gt;&quot;&lt;/span&gt; info@yourdomain.com

    &lt;span class=&quot;c&quot;&gt;# rsync worked but there was at least one mysqldump error&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# --------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else

      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;PARTIAL SUCCESS. File backup (rsync) was successful, but mysqldump reports errors: &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/server-backup.log

      &lt;span class=&quot;c&quot;&gt;# email the report&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: Server &amp;lt;servername&amp;gt; ran a local backup.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;File backup reports success, however mysqldump reports at least one problem.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Check &quot;&lt;/span&gt;| mail -s &lt;span class=&quot;s2&quot;&gt;&quot;Backup: Partial Success, &amp;lt;servername&amp;gt;&quot;&lt;/span&gt; info@yourdomain.com

  &lt;span class=&quot;k&quot;&gt;fi

fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Add the incremental backup script to &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/sbin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make executable&lt;/li&gt;
  &lt;li&gt;Set up cronjob&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Upload script&lt;/span&gt;
rsync --progress -a -v -rz -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 1234&quot;&lt;/span&gt; ~/bash-projects/remote-backup-scripts/servername/backup-servername daviduser@123.456.789.0:~/

&lt;span class=&quot;c&quot;&gt;# Move into position&lt;/span&gt;
sudo mv ~/backup-servername /usr/local/sbin

&lt;span class=&quot;c&quot;&gt;# Make executable&lt;/span&gt;
sudo chmod u+x /usr/local/sbin/backup-servername

&lt;span class=&quot;c&quot;&gt;# Open crontable&lt;/span&gt;
sudo crontab -e

&lt;span class=&quot;c&quot;&gt;# Add the following to the crontab, save and exit&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Run backup script every day at 3 am&lt;/span&gt;
00 03 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/local/sbin/backup-servername
&lt;span class=&quot;c&quot;&gt;# Send an email report from this cronjob&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MAILTO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;info@yourdomain.com&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;delete&quot;&gt;–delete&lt;/h2&gt;
&lt;p&gt;The delete option causes files that are not in source to be deleted from the target - and ONLY the target:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This tells rsync to delete extraneous files from the receiving side (ones that aren’t on the sending side), but only for the directories that are being synchronized. You must have asked rsync to send the whole directory … Files that are excluded from the transfer are also excluded from being deleted unless you use the –delete-excluded option or mark the rules as only matching on the sending side&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync man-page&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I originally used the &lt;code class=&quot;highlighter-rouge&quot;&gt;--delete&lt;/code&gt; flag on this script - thinking that it would be necessary to keep the latest incremental backup synchronised with the current source filesystem.&lt;/p&gt;

&lt;p&gt;However, &lt;code class=&quot;highlighter-rouge&quot;&gt;--delete&lt;/code&gt; has no effect when syncing into an empty directory, which is basically what happens when using the &lt;code class=&quot;highlighter-rouge&quot;&gt;--link-dest&lt;/code&gt; method of rsync. The directory specified by &lt;code class=&quot;highlighter-rouge&quot;&gt;--link-dest&lt;/code&gt; is used as a reference point, and any files &lt;strong&gt;in source&lt;/strong&gt; that are unchanged relative to this reference point are hardlinked to their exisiting inode in the reference directory.&lt;/p&gt;

&lt;p&gt;Files that are not in the source directory (because they have been deleted) are therefore not hardlinked in the backup directory.&lt;/p&gt;

&lt;p&gt;However there is a possibility that rsync is backing up to an incomplete directory that is left over from a previous failed run, and may contain things to delete.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;--delete&lt;/code&gt; is probably superfluous when using &lt;code class=&quot;highlighter-rouge&quot;&gt;--link-dest&lt;/code&gt;. The backup directory accurately reflects the source directory. However, we leave it in place in case of backing up to an incomplete directory.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;Note: Be careful deleting old snapshots. The old directory in it’s entirety should be properly archived and a new full backup snapshot should be taken to kick off the next round of incremental backups.&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;This warning is not necessary as using the &lt;code class=&quot;highlighter-rouge&quot;&gt;--link-dest&lt;/code&gt; option creates hard links. Thanks to aselinux for pointing this out in the comments.&lt;/p&gt;

&lt;h2 id=&quot;result&quot;&gt;Result&lt;/h2&gt;
&lt;p&gt;This will result in a backup directory on the production server, &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/backup&lt;/code&gt;, that contains dated incremental backups.&lt;/p&gt;

&lt;p&gt;The Production backup directory can then be targeted by a Backup server, again via rsync. Typically, this might involve:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Access to the backup directory by means of SSH public/private key pair&lt;/li&gt;
  &lt;li&gt;rrsync access for the backupuser - only rsync can run on the given SSH key, restricted to read-only&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Setup Secure &lt;a href=&quot;/2015/06/secure-rsync-between-servers/&quot;&gt;rsync link between servers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Run a cronjob on the backup server to read and rsync the backup directory on the Production server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.sanitarium.net/golug/rsync_backups_2010.html&quot;&gt;Excellent readable article on rsync&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.mikerubel.org/computers/rsync_snapshots/&quot;&gt;The original article by Mike Rubel&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://jimmyg.org/blog/2007/incremental-backups-using-rsync.html&quot;&gt;Incrementally numbered backups, using rsync&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://simon-davies.name/bash/backing-up-mysql-databases&quot;&gt;Database backup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stromberg.dnsalias.org/~strombrg/Backup.remote.html&quot;&gt;Example bash script using rsync for local and remote backups&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://earlruby.org/2013/05/creating-differential-backups-with-hard-links-and-rsync/&quot;&gt;rsync &amp;amp; cp for hardlinks&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.pointsoftware.ch/en/howto-local-and-remote-snapshot-backup-using-rsync-with-hard-links/&quot;&gt;Snapshot backup  - rsync with hardlinks - with detailed examples&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.thegeekstuff.com/2010/09/rsync-command-examples/&quot;&gt;Basic rsync examples&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync man page - surprisingly helpful!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;Time machine/rsync with good illustration of hard links&lt;/a&gt; - good sample “instant backup” script - backup every minute!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://serverfault.com/questions/249853/does-mysqldump-return-a-status&quot;&gt;mysqldump status&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Link Dest behaviour explation: &lt;a href=&quot;https://lists.samba.org/archive/rsync/2010-February/024649.html&quot;&gt;answer in the rsync mailing list archive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Link Dest and &lt;a href=&quot;https://lists.samba.org/archive/rsync/2010-February/024654.html&quot;&gt;deleting old snapshots&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 27 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/incremental-backup-on-server/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/incremental-backup-on-server/</guid>
      </item>
      
    
      
      <item>
        <title>Secure rsync Between Servers</title>
        <description>&lt;p&gt;This method allows for automatic incremental backups between servers.&lt;/p&gt;

&lt;h2 id=&quot;backup-server-pulls-from-production-server&quot;&gt;Backup Server Pulls from Production Server&lt;/h2&gt;
&lt;p&gt;Either server could initiate the sync - but if Production initiates, it would need write access to the Backup server. It is probably safest to give the Backup server read access to the Production server, so this guide assumes that the Backup machine initiates the sync.&lt;/p&gt;

&lt;p&gt;The files to be synced have been built by a local automatic rsync-based incremental backup script that runs on the Production server. This is because:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There is enough space on the Production machine (approx 8G out of 40G is in use)&lt;/li&gt;
  &lt;li&gt;Having an incremental backup on the Production server allows for quick restores in the event of non-catastrophic failure&lt;/li&gt;
  &lt;li&gt;Having backups on the production server is “belt and braces” - backups are stored in multiple locations&lt;/li&gt;
  &lt;li&gt;The script has root access and can build a complete set of backup files: /var/www/html/, Apache config files, MySQL config files, Database files (built by mysqldump)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;rrsync&lt;/code&gt; perl script (restricted rsync) to restrict rsync to a subdirectory declared in .ssh/authorized_keys. This works really well since our local incremental backup has written all the files we need to a single backup directory.&lt;/p&gt;

&lt;p&gt;The Incremental Backup that is being synced is &lt;a href=&quot;/2015/06/incremental-backup-on-server/&quot;&gt;described here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-backup-user-on-the-production-server&quot;&gt;Set up a Backup User on the Production Server&lt;/h2&gt;
&lt;p&gt;Set up a user without sudo privileges. This user is only going to be used to store backups - which provides another level of security.&lt;/p&gt;

&lt;p&gt;The backup user home directory will receive incremental backups, and hold the SSH public key to allow the remote backup server to connect - and that’s about it.&lt;/p&gt;

&lt;h2 id=&quot;set-up-an-ssh-key-pair-on-the-backup-server&quot;&gt;Set up an SSH Key Pair on the Backup Server&lt;/h2&gt;
&lt;p&gt;Because the backup script is designed to be triggered automatically by a cron job, the user that will be running the rsync command on the production server will be root.&lt;/p&gt;

&lt;p&gt;It is therefore important to transfer the public SSH key for &lt;strong&gt;the root user&lt;/strong&gt; to the backup target machine.&lt;/p&gt;

&lt;p&gt;In addition, the SSH key should NOT have a passphrase, so that connection can be made automatically. We will also limit the actions that can be carried out by this SSH connection.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Switch to root&lt;/span&gt;
su root

&lt;span class=&quot;c&quot;&gt;# Generate an SSH key pair, WITHOUT a passphrase&lt;/span&gt;
ssh-keygen -t rsa

&lt;span class=&quot;c&quot;&gt;# copy the public key to the backupuser account on the target Production machine&lt;/span&gt;
ssh-copy-id -p 1234 backupuser@123.456.789.0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;failure-to-copy-public-key&quot;&gt;Failure to Copy Public Key&lt;/h2&gt;
&lt;p&gt;If the public key doesn’t copy across, you’ll see an error message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/usr/bin/ssh-copy-id: INFO: attempting to log &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;with the new key&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; remain to be installed -- &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;you are prompted now it is to install the new keys
Permission denied &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;publickey&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This means that the remote server has refused the connection.&lt;/p&gt;

&lt;p&gt;In my case, this is because I usually set up servers such that access is via SSH key only - with password authentication disabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To copy a public SSH key to a remote server, password SSH login must be enabled on the remote server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To enable password login:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SSH into the remote server&lt;/li&gt;
  &lt;li&gt;Configure SSH: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Edit to allow password authentication: &lt;code class=&quot;highlighter-rouge&quot;&gt;PasswordAuthentication yes&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Save &amp;amp; exit, then reload the SSH server: &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo reload ssh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the key has been copied across (which will require password entry for the relevant user), test SSH access (as prompted). If it works, you can safely disable password login on the remote machine.&lt;/p&gt;

&lt;h2 id=&quot;limit-actions-for-this-ssh-connection-to-restricted-rsync&quot;&gt;Limit Actions for this SSH Connection to Restricted rsync&lt;/h2&gt;
&lt;p&gt;Using an SSH key without a passphrase makes it possible to automate remote tasks - a user-entered passphrase is not required for key decryption.&lt;/p&gt;

&lt;p&gt;Automation of backup tasks is essential - if backup relies on human intervention, sooner or later it will get missed or messed up. However, using SSH keys without a passphrase is a security risk - is someone had access to the backup server, they would be easily able to access the remote Production server.&lt;/p&gt;

&lt;p&gt;To prevent this, SSH allows restriction of the commands that can be executed by a specific set of keys. This is accomplished by editing the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/.ssh/authorized_keys&lt;/code&gt; file for the backup user on the Production server.&lt;/p&gt;

&lt;p&gt;A script called rrsync (which stands for restricted rsync) is provided with rsync specifically to ease the restricting keys to be used only for rsync via .ssh/authorized_keys.&lt;/p&gt;

&lt;p&gt;On Ubuntu, the script is located here: &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/doc/rsync/scripts/rrsync.gz&lt;/code&gt;. The script needs to be unzipped and installed under &lt;code class=&quot;highlighter-rouge&quot;&gt;user/local/bin&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Copy the archive rrsync script to /usr/local/bin&lt;/span&gt;
sudo cp /usr/share/doc/rsync/scripts/rrsync.gz  /usr/local/bin/

&lt;span class=&quot;c&quot;&gt;# Unzip the script&lt;/span&gt;
sudo gzip -d   /usr/local/bin/rrsync.gz

&lt;span class=&quot;c&quot;&gt;# Give it correct permissions&lt;/span&gt;
sudo chmod 755 /usr/local/bin/rrsync&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once &lt;code class=&quot;highlighter-rouge&quot;&gt;rrsync&lt;/code&gt; is in place, we can lock down access for our SSH key by amending the &lt;code class=&quot;highlighter-rouge&quot;&gt;/home/backupuser/.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Open the public key for the backup user on the Production Server. This will constitute a single line of text:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /home/backupuser/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Prepend the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin/rrsync -ro /home/path-to/backup/&quot;&lt;/span&gt;,no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;command=&quot;/usr/local/bin/rrsync ...&quot;&lt;/code&gt; restricts access of that particular public key - only the given command can be executed&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;...-ro /home/path-to/backup/&quot;&lt;/code&gt; gives &lt;strong&gt;read-only&lt;/strong&gt; access to the specified directory&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;no-*&lt;/code&gt; options further restrict what actions can be carried out with the public key.&lt;/li&gt;
  &lt;li&gt;Note that the full path is need to reference rrsync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try and SSH into the Production machine from the Backup server you should now see a message like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PTY allocation request failed on channel 0
/usr/local/bin/rrsync: Not invoked via sshd
Use &lt;span class=&quot;s1&quot;&gt;'command=&quot;/usr/local/bin/rrsync [-ro] SUBDIR&quot;'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;front of lines &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /home/backupuser/.ssh/authorized_keys
Connection to 123.45.67.89 closed.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;command-rsync-from--backup-server&quot;&gt;Command rsync from  Backup Server&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; After the above amendment to the &lt;code class=&quot;highlighter-rouge&quot;&gt;authorized_keys&lt;/code&gt; file, the final path from the Backup servers point of view is now “/”:&lt;/p&gt;

&lt;p&gt;Sample rsync command from the Backup server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rsync --log-file&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.rsyncd.log --progress -az -H -e &lt;span class=&quot;s2&quot;&gt;&quot;ssh -p 1234&quot;&lt;/span&gt; backupuser@123.456.789.0:/ ~/backup-target-directory&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This specifies:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-a: archive mode; equals -rlptgoD (no -H,-A,-X)&lt;/li&gt;
  &lt;li&gt;-z: Compress file data during the transfer&lt;/li&gt;
  &lt;li&gt;-H: Maintain hardlinks (important due to our incremental backup)&lt;/li&gt;
  &lt;li&gt;-e “ssh -p 1234”: connect via SSH on port 1234&lt;/li&gt;
  &lt;li&gt;See &lt;a href=&quot;http://linux.die.net/man/1/rsync&quot;&gt;rsync man&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.guyrutenberg.com/2014/01/14/restricting-ssh-access-to-rsync/&quot;&gt;http://www.guyrutenberg.com/2014/01/14/restricting-ssh-access-to-rsync/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.debian-administration.org/users/lee/weblog/40&quot;&gt;https://www.debian-administration.org/users/lee/weblog/40&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://positon.org/rsync-command-restriction-over-ssh&quot;&gt;http://positon.org/rsync-command-restriction-over-ssh&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://surniaulula.com/2014/02/21/force-rsync-command-via-ssh-but-allow-any-directory/&quot;&gt;http://surniaulula.com/2014/02/21/force-rsync-command-via-ssh-but-allow-any-directory/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ramblings.narrabilis.com/using-rsync-with-ssh&quot;&gt;http://ramblings.narrabilis.com/using-rsync-with-ssh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 17 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/secure-rsync-between-servers/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/secure-rsync-between-servers/</guid>
      </item>
      
    
      
      <item>
        <title>Setup Logwatch</title>
        <description>&lt;p&gt;This article refers to Logwatch on Ubuntu 14.04 LTS.&lt;/p&gt;

&lt;p&gt;Logwatch needs a mail transfer agent. Typically we use Exim4 in send-only mode.&lt;/p&gt;

&lt;p&gt;To install Logwatch, run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt; then install Logwatch with:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install logwatch&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Move config files - don’t edit the originals:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/logwatch/conf&lt;/code&gt; directory is first searched for files with the same name and relative location as the &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/share/logwatch/default.conf&lt;/code&gt; directory. Variables declared in
these files override the defaults.&lt;/p&gt;

  &lt;p&gt;From: &lt;a href=&quot;http://www.stellarcore.net/logwatch/tabs/docs/HOWTO-Customize-LogWatch.html&quot;&gt;http://www.stellarcore.net/logwatch/tabs/docs/HOWTO-Customize-LogWatch.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If using Apache server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /usr/share/logwatch/default.conf/logfiles/http.conf /etc/logwatch/conf/logfiles/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then add *combined.log files to the list&lt;/p&gt;

&lt;h2 id=&quot;configure-logwatch&quot;&gt;Configure Logwatch&lt;/h2&gt;

&lt;p&gt;Edit config:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/logwatch/conf/logwatch.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set email address, logs to be checked/ignored etc.&lt;/p&gt;

&lt;h2 id=&quot;cache&quot;&gt;Cache&lt;/h2&gt;
&lt;p&gt;This may need to be manualy created, if Logwatch throws an error:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir /var/cache/logwatch&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…then run logwatch as sudo.&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-custom-cronjob-for-logwatch&quot;&gt;Set up a Custom Cronjob for Logwatch&lt;/h2&gt;
&lt;p&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/cron.daily/00logwatch&lt;/code&gt; to include the admin email:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Check if removed-but-not-purged&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; -x /usr/share/logwatch/scripts/logwatch.pl &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0

&lt;span class=&quot;c&quot;&gt;#execute&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#/usr/sbin/logwatch --output mail&lt;/span&gt;
/usr/sbin/logwatch --mailto info@yourdomain.com

&lt;span class=&quot;c&quot;&gt;#Note: It's possible to force the recipient in above command&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#Just pass --mailto address@a.com instead of --output mail&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The run time is tied in to the time of the daily cron job. To change, remove &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/cron.daily/00logwatch&lt;/code&gt; and add a new cronjob. Not tested:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Run every day, @ midnight&lt;/span&gt;
sudo crontab -e

0 0 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /usr/sbin/logwatch&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/Logwatch&quot;&gt;https://help.ubuntu.com/community/Logwatch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.unixmen.com/installing-configuring-logwatch-ubuntu-14-04/&quot;&gt;http://www.unixmen.com/installing-configuring-logwatch-ubuntu-14-04/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-use-logwatch-log-analyzer-and-reporter-on-a-vps&quot;&gt;https://www.digitalocean.com/community/tutorials/how-to-install-and-use-logwatch-log-analyzer-and-reporter-on-a-vps&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.stellarcore.net/logwatch/tabs/docs/HOWTO-Customize-LogWatch.html&quot;&gt;Definitive Guide on Customising Logwatch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jviz.research.iat.sfu.ca/wiki/index.php?title=Customizing_Logwatch&quot;&gt;Even More Definitive, though focused on Gentoo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/logwatch/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/logwatch/</guid>
      </item>
      
    
      
      <item>
        <title>LAMP Stack Setup</title>
        <description>&lt;p&gt;Before starting, follow the guidelines on setting up Ubuntu 14.04 LTS.&lt;/p&gt;

&lt;h2 id=&quot;install-apache&quot;&gt;Install Apache&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get update
sudo apt-get install apache2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check by visiting the IP address in the browser - you should see the default “Apache 2 Ubuntu” intro page. This shows some useful info on config files - if you’re not familiar with Apache2 config, it might be worth a look.&lt;/p&gt;

&lt;h2 id=&quot;install-mysql&quot;&gt;Install MySQL&lt;/h2&gt;
&lt;p&gt;We need some databases!&lt;/p&gt;

&lt;p&gt;Install MySQL and some helper packages:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;sudo apt-get install mysql-server php5-mysql&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Open up keepass/KeepassX, set a &lt;strong&gt;strong&lt;/strong&gt; password for MySQL root.&lt;/p&gt;

&lt;p&gt;After installation, take extra measures to secure MySQL:&lt;/p&gt;

&lt;p&gt;Install MySQL system tables - tell MySQL to create a database directory structure to store info:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-startinline&quot; data-lang=&quot;startinline&quot;&gt;sudo mysql_install_db&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Run a MySQL security script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mysql_secure_installation&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;During execution of this script, you will first get the option to reset root password. You won’t need to do this, because you’ve already set a hardcore password, so answer “n”. Thereafter, hit return to accept the default (Y) answer for each question. This deletes some dummy DBs, disallows remote root login, removes anonymous users and reloads the privilege tables so that changes take effect immediately.&lt;/p&gt;

&lt;h2 id=&quot;install-php&quot;&gt;Install PHP&lt;/h2&gt;
&lt;p&gt;Use apt to install:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Modify the way that Apache serves files, to give priority to PHP:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/mods-enabled/dir.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…bring the php index file forward in the hierarchy, so the directive looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;lt;IfModule mod_dir.c&amp;gt;
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
&amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;View available PHP modules:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt-cache search php5-&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you need additional PHP modules (e.g. php5-curl):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install php5-curl&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Increase the max filesize for uploads, because … clients. You need to edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/php5/apache2/php.ini&lt;/code&gt;, since this is the settings file used by Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/php5/apache2/php.ini

&lt;span class=&quot;c&quot;&gt;# hit ctrl+w to open search&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# enter upload_max_filesize&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Amend:&lt;/span&gt;
; Maximum allowed size &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 40M

&lt;span class=&quot;c&quot;&gt;# After saving, restart Apache&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To install additional PHP modules, see the &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-14-04&quot;&gt;Justin Ellingwood article&lt;/a&gt; on Digital Ocean.&lt;/p&gt;

&lt;h2 id=&quot;test-php-setup&quot;&gt;Test PHP Setup&lt;/h2&gt;
&lt;p&gt;Check PHP by outputting &lt;code class=&quot;highlighter-rouge&quot;&gt;phpinfo();&lt;/code&gt; in a php file and accessing via a browser:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /var/www/html/info.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Copy this into the file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;lt;?php phpinfo&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;; ?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Check in a browser(e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;123.456.78.90/info.php&lt;/code&gt;), save the HTML file locally for your records, then remove:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo rm /var/www/html/info.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;phpmyadmin&quot;&gt;PHPMyAdmin&lt;/h2&gt;
&lt;p&gt;Install - you will need to enter the root MySQL password:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install phpmyadmin apache2-utils&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ol&gt;
  &lt;li&gt;Hit space then tab to select Apache2&lt;/li&gt;
  &lt;li&gt;Choose “yes” when asked “Configure database for phpmyadmin with dbconfig-common?”&lt;/li&gt;
  &lt;li&gt;Enter MySQL password when prompted&lt;/li&gt;
  &lt;li&gt;Enter password for the phpmyadmin user&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Make sure your password manager is open!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once installed, PHPMyAdmin needs to be added to the Apache config file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/apache2.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add the following line to the end of &lt;code class=&quot;highlighter-rouge&quot;&gt;apache2.conf&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Include /etc/phpmyadmin/apache.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;secure-phpmyadmin-with-a-htaccess-file&quot;&gt;Secure PHPMyAdmin with a .htaccess File&lt;/h2&gt;
&lt;p&gt;Configure the phpmyadmin directory to allow .htaccess rules:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/phpmyadmin/apache.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add &lt;code class=&quot;highlighter-rouge&quot;&gt;AllowOverride All&lt;/code&gt; under the the first directory block, straight after “DirectoryIndex…”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;lt;Directory /usr/share/phpmyadmin&amp;gt;
        Options FollowSymLinks
        DirectoryIndex index.php
        AllowOverride All
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set up .htaccess file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /usr/share/phpmyadmin/.htaccess&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Enter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;AuthType Basic
AuthName &lt;span class=&quot;s2&quot;&gt;&quot;Restricted Files&quot;&lt;/span&gt;
AuthUserFile /etc/apache2/.phpmyadmin.htpasswd
Require valid-user&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create a htpasswd file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo htpasswd -c /etc/apache2/.phpmyadmin.htpasswd username&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…where username is the username you want to give access to (doesn’t need to be an existing sytem user).&lt;/p&gt;

&lt;p&gt;You’ll be prompted to enter a password for this user (twice). Restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The PHPMyAdmin directory is now password protected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If your system doesn’t recognise the &lt;code class=&quot;highlighter-rouge&quot;&gt;htpasswd&lt;/code&gt; command - you receive the message &lt;code class=&quot;highlighter-rouge&quot;&gt;htpasswd: command not found&lt;/code&gt;, you may need to install the apache-2 utils module:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo apt-get install apache2-utils&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once you’ve done this, you can re-try the &lt;code class=&quot;highlighter-rouge&quot;&gt;htpasswd&lt;/code&gt; command and it should work. Don’t forget to restart Apache.&lt;/p&gt;

&lt;h2 id=&quot;access-phpmyadmin&quot;&gt;Access PHPMyAdmin&lt;/h2&gt;
&lt;p&gt;Use the MySQL root username &amp;amp; password.&lt;/p&gt;

&lt;p&gt;See this &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-12-04&quot;&gt;Excellent &amp;amp; comprehensive article&lt;/a&gt; - most of the current instructions drawn from here.&lt;/p&gt;

&lt;h2 id=&quot;set-up-apache-virtual-hosts&quot;&gt;Set Up Apache Virtual Hosts&lt;/h2&gt;
&lt;p&gt;Multiple sites on a single server/VPS.&lt;/p&gt;

&lt;h2 id=&quot;create-directory-structure&quot;&gt;Create Directory Structure&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkdir -p /var/www/html/example.com/public_html
sudo mkdir -p /var/www/html/example2.com/public_html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The -p flag creates intermediate directories as required.&lt;/p&gt;

&lt;p&gt;Give permissions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /var/www/example.com/public_html
sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /var/www/test.com/public_html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; WordPress is going to need the www-data to have ownership of the public_html subdirectories to allow file upload etc. - for the time being, give ownership to the current user - pass ownership to www-data later.&lt;/p&gt;

&lt;p&gt;Set Permissions to 755 for directories:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chmod -R 755 /var/www&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add index.html demo pages if necessary.&lt;/p&gt;

&lt;h2 id=&quot;create-config-files&quot;&gt;Create config files:&lt;/h2&gt;
&lt;p&gt;Create a config file for each site:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/yoursite.com.conf&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Use this as a template:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*:80&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        ServerName yoursite.com
        ServerAlias www.yoursite.com
        ServerAdmin info@carawebs.com
        DocumentRoot /var/www/html/yoursite.com/public_html
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;Directory&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;/var/www/html/yoursite.com/public_html&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                Options -Indexes +FollowSymLinks
                AllowOverride All
                Require all granted
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Directory&amp;gt;&lt;/span&gt;
        ErrorLog ${APACHE_LOG_DIR}/yoursite.com.error.log
        CustomLog ${APACHE_LOG_DIR}/yoursite.com.access.log combined
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This config block sets the correct server name, alias and document root. Directory browsing is disallowed, and .htaccess files are allowed.&lt;/p&gt;

&lt;p&gt;Site specific error reporting is added - log files are located here: &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/apache2/yoursite.com.error.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enable the site using &lt;code class=&quot;highlighter-rouge&quot;&gt;a2ensite&lt;/code&gt;and restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2ensite yoursite.com.conf
sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;enable-apache-rewrites&quot;&gt;Enable Apache Rewrites&lt;/h2&gt;
&lt;p&gt;Enabling the Apache rewrite module will be essential it you’re using pretty permalinks. Enable the module &amp;amp; restart Apache:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod rewrite &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo service apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo a2enmod rewrite &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo /etc/init.d/apache2 restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;harden-apache&quot;&gt;Harden Apache&lt;/h2&gt;
&lt;p&gt;Prevent the Apache server signature that is printed as part of a web request - this is not needed and gives would-be hackers info about your server.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/apache2/conf-enabled/security.conf

&lt;span class=&quot;c&quot;&gt;# Set ServerSignature Off&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart Apache for changes to take effect.&lt;/p&gt;

&lt;p&gt;Prevent direct access of VCS files  by adding this block to &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/apache2/conf-enabled/security.conf&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&amp;lt;DirectoryMatch &lt;span class=&quot;s2&quot;&gt;&quot;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;git&quot;&lt;/span&gt;&amp;gt;
   Require all denied
&amp;lt;/DirectoryMatch&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You could also prevent access to source control files by adding this to a &lt;code class=&quot;highlighter-rouge&quot;&gt;.htaccess&lt;/code&gt; file in the site root:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# ==================================================================&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Prevent .git access&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ==================================================================&lt;/span&gt;

RedirectMatch 404 /&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;h2 id=&quot;basic-setup&quot;&gt;Basic Setup&lt;/h2&gt;
&lt;p&gt;Guidelines &amp;amp; Tutorials to help set up a secure LAMP stack.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/getting-started&quot;&gt;Setup new linode VPS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Post-setup actions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/additional-recommended-steps-for-new-ubuntu-14-04-servers&quot;&gt;Basic Security/Firewall, Timezones, Swapfile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/security/securing-your-server&quot;&gt;Basic Security Measures - Manual config of firewall&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;security&quot;&gt;Security&lt;/h2&gt;
&lt;p&gt;Good Digital Ocean security guide, including adding new user, setting up public key authentication, SSH configuration. &lt;strong&gt;Highly recommended:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04&quot;&gt;Digital Ocean Server Setup, Ubuntu 14.04&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps&quot;&gt;Digital Ocean: Securing a Linux VPS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.fire-development.com/2014/09/23/prepare-ubuntu-for-wordpress-installation/&quot;&gt;Focus on WordPress&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;lamp-stack-including-phpmyadmin&quot;&gt;LAMP Stack: Including PHPMyAdmin&lt;/h2&gt;

&lt;p&gt;Comprehensive instructions on how to set up a LAMP stack on a VPS running Ubuntu 14.04:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-14-04&quot;&gt;LAMP Stack, Ubuntu 14.04, Digital Ocean Guidelines &lt;strong&gt;Very good!&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set up PHPMyAdmin, including extra security measures (password protected directory with .htaccess):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-12-04&quot;&gt;PHPMyAdmin Setup, Ubuntu 12.04&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create SSL Certificate:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-apache-for-ubuntu-12-04&quot;&gt;Create SSL Certificate for Apache on Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;set-up-mailserver&quot;&gt;Set Up Mailserver&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/email/exim/sendonly-mail-server-with-exim-on-debian-6-squeeze/&quot;&gt;Send only Exim Mailserver, Debian&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-the-send-only-mail-server-exim-on-ubuntu-12-04&quot;&gt;Install Exim, Ubuntu 12.04&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-an-spf-record-to-prevent-spoofing-improve-e-mail-reliability&quot;&gt;SPF Records: Reduce Spoofing Spam&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://thanhsiang.org/faqing/node/185&quot;&gt;http://thanhsiang.org/faqing/node/185&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dev.antoinesolutions.com/ubuntu-14.04-trusty/install-and-configure-exim-mail-server-on-ubuntu-14.04&quot;&gt;http://dev.antoinesolutions.com/ubuntu-14.04-trusty/install-and-configure-exim-mail-server-on-ubuntu-14.04&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exim Cheatsheet:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://bradthemad.org/tech/notes/exim_cheatsheet.php&quot;&gt;http://bradthemad.org/tech/notes/exim_cheatsheet.php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;load-testing-a-server&quot;&gt;Load Testing a Server&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/tools-reference/tools/load-testing-with-siege&quot;&gt;Testing with Siege&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;os-upgradespatches-ubuntu&quot;&gt;OS Upgrades/Patches: Ubuntu&lt;/h2&gt;
&lt;p&gt;The OS is patched very promptly when security issues arise, and it is essential that your server is updated/upgraded regularly. Usually, &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt; followed by &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get upgrade&lt;/code&gt; is sufficient. The Ubuntu “Message of the Day” generally advises when upgrading is necessary - but it pays to stay up to date with OS developments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.ubuntu.com/usn/trusty/&quot;&gt;Ubuntu Notices&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.ubuntu.com/usn/rss.xml&quot;&gt;RSS Feed of the above&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;harden-apache-1&quot;&gt;Harden Apache&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://websectips.com/articles/10-apache-security-hardening-tips&quot;&gt;http://websectips.com/articles/10-apache-security-hardening-tips&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 15 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/lamp-stack-setup/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/lamp-stack-setup/</guid>
      </item>
      
    
      
      <item>
        <title>Ubuntu 14.04 LTS Server Setup</title>
        <description>&lt;p&gt;This article is a cheatsheet/guidelines for the secure setup of Ubuntu 14.04 LTS server.&lt;/p&gt;

&lt;p&gt;The content has been largely drawn from this &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/additional-recommended-steps-for-new-ubuntu-14-04-servers&quot;&gt;Digital Ocean article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once a new server is created, you should follow these setup guidelines as soon as possible. Check the &lt;code class=&quot;highlighter-rouge&quot;&gt;auth.log&lt;/code&gt; file for malicious access attempts:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;~~~
sudo cat /var/log/auth.log | grep &lt;span class=&quot;s1&quot;&gt;'sshd.*Invalid'&lt;/span&gt;
~~~&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Malicious log in attempts begin almost immediately - presumably, would-be hackers are trying a range of IP addresses and knocking on doors, looking for low-hanging fruit. For this reason, the initial VPS setup should &lt;strong&gt;definitely include a strong root password&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;set-fqdnhostname&quot;&gt;Set FQDN/Hostname&lt;/h2&gt;

&lt;p&gt;To set the hostname to “archimedes”, edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hostname&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;archimedes&quot;&lt;/span&gt; &amp;gt; /etc/hostname
hostname -F /etc/hostname&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If it exists, edit the file &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/default/dhcpcd&lt;/code&gt; to comment out the SET_HOSTNAME directive.&lt;/p&gt;

&lt;h3 id=&quot;edit-etchosts&quot;&gt;Edit /etc/hosts&lt;/h3&gt;
&lt;p&gt;Edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; - amend the localhost entry, and add a new line referring to the FQDN.&lt;/p&gt;

&lt;p&gt;This should be in the format: &lt;code class=&quot;highlighter-rouge&quot;&gt;IP-Address-of-system hostname.domainname.TLD hostname&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;127.0.0.1 localhost.localdomain localhost
123.345.567.78 archimedes.your-main-domain.com archimedes&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add ipV6 if necessary, e.g.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;1b00:1b00::f0f0:11aa:aa98:bdf4 archimedes.your-main-domain.com archimedes&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;restart-the-hostname-service&quot;&gt;Restart the hostname service&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/etc/init.d/hostname restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-timezone&quot;&gt;Set Timezone&lt;/h2&gt;
&lt;p&gt;Activate wizard, follow instructions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;dpkg-reconfigure tzdata&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-new-user&quot;&gt;Create New User&lt;/h2&gt;
&lt;p&gt;Create a new user:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;adduser daviduser&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Answer the questions, add password, hit enter.&lt;/p&gt;

&lt;p&gt;Give new user sudo privileges:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;gpasswd -a daviduser sudo&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;generate-ssh-key-pair-on-local-machine&quot;&gt;Generate SSH Key Pair on Local Machine&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;You can re-use and existing one if it already exists&lt;/strong&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add a passphrase.&lt;/p&gt;

&lt;h2 id=&quot;copy-public-ssh-key-to-server&quot;&gt;Copy Public SSH Key to Server&lt;/h2&gt;
&lt;p&gt;The easiest way to do this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-copy-id daviduser@123.45.56.78&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You will be prompted for the user’s password…and that’s it!&lt;/p&gt;

&lt;h2 id=&quot;reboot-server-from-command-line&quot;&gt;Reboot Server From Command Line&lt;/h2&gt;
&lt;p&gt;This is sometimes prompted for/required during the setup process:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo reboot&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;harden-ssh-access&quot;&gt;Harden SSH Access&lt;/h2&gt;

&lt;p&gt;Backup config:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restrict root login so it is only via SSH key (NOT Password):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Amend the &lt;code class=&quot;highlighter-rouge&quot;&gt;PermitRootLogin&lt;/code&gt; entry:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PermitRootLogin without-password&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ctrl+o to save, Ctrl+x to exit. Then reload ssh:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo reload ssh&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Try and connect in a new terminal BEFORE CLOSING THE OPEN TERMINAL!!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Test logging in to root via SSH - it will allow password entry, but the response shoudl be: “Permission denied, please try again.”&lt;/p&gt;

&lt;h2 id=&quot;firewall&quot;&gt;Firewall&lt;/h2&gt;
&lt;p&gt;Set up ‘Uncomplicated Firewall’: ufw.&lt;/p&gt;

&lt;p&gt;Allow on the custom SSH port:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ufw allow 4444/tcp&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Allow port 80, for internet:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ufw allow 80/tcp&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To allow https traffic, open port 443:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ufw allow 443/tcp&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Show the exceptions you have added:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ufw show added&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Enable the firewall:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo ufw &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;More info on &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-setup-a-firewall-with-ufw-on-an-ubuntu-and-debian-cloud-server&quot;&gt;configuring ufw&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;swapfile&quot;&gt;Swapfile&lt;/h2&gt;
&lt;p&gt;Probably not necessary but may prevent server crashing in the event of high traffic. Accessing data stored on disk (rather than memory) is slow.&lt;/p&gt;

&lt;p&gt;Generally recommended that the size of the swapfile should be 2 x RAM.&lt;/p&gt;

&lt;p&gt;Determine RAM:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# return memory in MB&lt;/span&gt;
free -m&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Use fallocate to allocate space to swap file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo fallocate -l 4G /swapfile&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;fallocate is used to manipulate the allocated disk space for a file, either to deallocate or preallocate it.  For filesystems which support the fallocate system call, preallocation is done quickly by allocating blocks and marking them as uninitialized, requiring no IO to the data blocks.  This is much faster than creating a file by filling it with zeros.
&lt;a href=&quot;http://man7.org/linux/man-pages/man1/fallocate.1.html&quot;&gt;fallocate man page&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Give correct permissions to swapfile - restrict access so other users/processors can’t see it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chmod 600 /swapfile&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Format the file for swap:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo mkswap /swapfile&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make the file available for swap:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo swapon /swapfile&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make it available for swap at boot by amending &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fstab&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo sh -c &lt;span class=&quot;s1&quot;&gt;'echo &quot;/swapfile none swap sw 0 0&quot; &amp;gt;&amp;gt; /etc/fstab'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://sharadchhetri.com/2013/07/23/set-hostname-and-fqdn-in-ubuntu-without-reboot/&quot;&gt;Set hostname &amp;amp; FQDN in Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 14 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/ubuntu-14-04-server-setup/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/ubuntu-14-04-server-setup/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Body Classes</title>
        <description>&lt;p&gt;Adds extra body classes by hooking into the ‘body_class’ filter.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://codex.wordpress.org/Plugin_API/Filter_Reference/body_class&quot;&gt;WP Codex on &lt;code class=&quot;highlighter-rouge&quot;&gt;body_class()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;/**
 * Add page slug to `body_class()` classes if it doesn't exist
 * &amp;amp; add user role to body class
 *
 * Hooks into the `body_class` filter.
 *
 * @package UserHelpers
 * @param  array $classes Passed in from the body_class filter
 * @return array $classes Extra classes added
 *
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;carawebs_body_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$classes&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;c1&quot;&gt;// Add post/page slug
&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// ---------------------------------------------------------------------------
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_single&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_archive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is_front_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_bbpress&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;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;in_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_permalink&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;nv&quot;&gt;$classes&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;p&quot;&gt;{&lt;/span&gt;

      &lt;span class=&quot;nv&quot;&gt;$classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_permalink&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;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Check to see if the user is logged in, and if they are, add their role to the body class.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// -------------------------------------------------------------------------
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;is_user_logged_in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;is_front_page&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;nv&quot;&gt;$current_user&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_get_current_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Current user object
&lt;/span&gt;      &lt;span class=&quot;nv&quot;&gt;$current_user_id&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$current_user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// Current user ID
&lt;/span&gt;      &lt;span class=&quot;nv&quot;&gt;$user_role&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebs_get_user_role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$current_user_id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$user_role&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'-role'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// append modifier to avoid confusion with pages having same name
&lt;/span&gt;      &lt;span class=&quot;nv&quot;&gt;$classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;          &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$user_role&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;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$classes&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;nx&quot;&gt;add_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'body_class'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'carawebs_body_class'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 04 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/wp-body-classes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/wp-body-classes/</guid>
      </item>
      
    
      
      <item>
        <title>Select Form Element Styling</title>
        <description>&lt;p&gt;Select tags are commonly used in forms:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;select&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;volvo&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Volvo&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;saab&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Saab&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mercedes&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Mercedes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;option&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;audi&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Audi&lt;span class=&quot;nt&quot;&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This looks unstyled and brutal:
&lt;select&gt;
  &lt;option value=&quot;volvo&quot;&gt;Volvo&lt;/option&gt;
  &lt;option value=&quot;saab&quot;&gt;Saab&lt;/option&gt;
  &lt;option value=&quot;mercedes&quot;&gt;Mercedes&lt;/option&gt;
  &lt;option value=&quot;audi&quot;&gt;Audi&lt;/option&gt;
&lt;/select&gt;&lt;/p&gt;

&lt;h2 id=&quot;impossible-to-style&quot;&gt;Impossible to Style&lt;/h2&gt;
&lt;p&gt;It’s not possible to apply style rules to select/option tags directly, unless I’, missing something.&lt;/p&gt;

&lt;h2 id=&quot;the-bootstrap-select-solution&quot;&gt;The bootstrap-select Solution&lt;/h2&gt;
&lt;p&gt;Using &lt;a href=&quot;http://silviomoreto.github.io/bootstrap-select/&quot;&gt;Bootstrap-select&lt;/a&gt;, Bootstrap 3 dropdown styles can be added to the option dropdown.&lt;/p&gt;

&lt;h2 id=&quot;bootstrap-select-install&quot;&gt;Bootstrap-Select Install&lt;/h2&gt;
&lt;p&gt;Bootstrap select &lt;a href=&quot;https://libraries.io/bower/bootstrap-select&quot;&gt;on Bower&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Install via Bower: &lt;code class=&quot;highlighter-rouge&quot;&gt;bower install bootstrap-select&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Enqueue JS files&lt;/li&gt;
  &lt;li&gt;Use bootstrap-select styles&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;using-with-sage&quot;&gt;Using with Sage&lt;/h2&gt;
&lt;p&gt;Refers to the &lt;a href=&quot;https://github.com/roots/sage&quot;&gt;Sage WordPress Starter Theme&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;bower.json&lt;/code&gt; (see below) and run &lt;code class=&quot;highlighter-rouge&quot;&gt;bower install&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make the &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap-select&lt;/code&gt; style rules available - convert from CSS/LESS into SASS&lt;/li&gt;
  &lt;li&gt;One option: copy (via gulp if necessary) &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap-select.css&lt;/code&gt; into a new &lt;code class=&quot;highlighter-rouge&quot;&gt;_bootstrap-select.scss&lt;/code&gt; file, and import this in &lt;code class=&quot;highlighter-rouge&quot;&gt;assets/styles/main.scss&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amended bower.json will build the &lt;code class=&quot;highlighter-rouge&quot;&gt;bootstrap-select&lt;/code&gt; javascript file into &lt;code class=&quot;highlighter-rouge&quot;&gt;main.js&lt;/code&gt; by means of &lt;a href=&quot;https://github.com/austinpray/asset-builder&quot;&gt;Asset Builder&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;bowerjson&quot;&gt;bower.json&lt;/h2&gt;
&lt;p&gt;Note that bootstrap-select has been added to the “overrides” block.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;homepage&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://roots.io/sage/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;authors&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;Ben Word &amp;lt;ben@benword.com&amp;gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;license&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;MIT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;private&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;modernizr&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;2.8.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;jquery&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1.11.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;bootstrap-sass-official&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;3.3.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;bootstrap-select&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~1.7.2&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;overrides&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;modernizr&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;./modernizr.js&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;bootstrap-select&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;./dist/js/bootstrap-select.js&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;bootstrap-sass-official&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/stylesheets/_bootstrap.scss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/transition.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/alert.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/button.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/carousel.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/collapse.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/dropdown.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/modal.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/tooltip.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/popover.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/scrollspy.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/tab.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/javascripts/bootstrap/affix.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/fonts/bootstrap/glyphicons-halflings-regular.eot&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/fonts/bootstrap/glyphicons-halflings-regular.svg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/fonts/bootstrap/glyphicons-halflings-regular.ttf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/fonts/bootstrap/glyphicons-halflings-regular.woff&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;./assets/fonts/bootstrap/glyphicons-halflings-regular.woff2&quot;&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;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;using-the-library&quot;&gt;Using the library&lt;/h2&gt;
&lt;p&gt;The easy bit - just create your &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;select&amp;gt;&lt;/code&gt; with the &lt;code class=&quot;highlighter-rouge&quot;&gt;.selectpicker&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;For more options, see &lt;a href=&quot;http://silviomoreto.github.io/bootstrap-select/&quot;&gt;the docs&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 04 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/select-styling/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/select-styling/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up SPF Records</title>
        <description>&lt;p&gt;Publishing a Sender Policy Framework (SPF) Record in your domain’s DNS specifies which server IP addresses are allowed to send emails from your domain.&lt;/p&gt;

&lt;p&gt;Having a properly set up SPF record makes it less likely that outgoing mail will be tagged as spam.&lt;/p&gt;

&lt;h2 id=&quot;return-as-a-txt-record&quot;&gt;Return as a TXT Record&lt;/h2&gt;
&lt;p&gt;Although it appears that best practice is to publish SPF records via DNS as both a SPF and TXT record, the DNS management utilities for some hosts only provide for the addition of txt records&lt;/p&gt;

&lt;p&gt;For a good description of SPF as TXT records, see &lt;a href=&quot;http://mxtoolbox.com/problem/spf/txt-record&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;spf-generators&quot;&gt;SPF Generators&lt;/h2&gt;
&lt;p&gt;From the MS Generator:
&lt;code class=&quot;highlighter-rouge&quot;&gt;v=spf1 a mx ip4:123.45.678.90 mx:mail.yourdomain.com -all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add text record with &lt;code class=&quot;highlighter-rouge&quot;&gt;-all&lt;/code&gt; amended to &lt;code class=&quot;highlighter-rouge&quot;&gt;~all&lt;/code&gt;, which allows a ‘soft fail’:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;v=spf1 a mx ip4:123.45.678.90 mx:mail.yourdomain.com ~all
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This assumes that there is also an mx record for a mailserver for the domain in question.&lt;/p&gt;

&lt;h2 id=&quot;check-spf-record&quot;&gt;Check SPF Record&lt;/h2&gt;
&lt;p&gt;Use &lt;a href=&quot;http://mxtoolbox.com/&quot;&gt;this tool&lt;/a&gt; to check SPF records on your domain.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-use-an-spf-record-to-prevent-spoofing-improve-e-mail-reliability&quot;&gt;https://www.digitalocean.com/community/tutorials/how-to-use-an-spf-record-to-prevent-spoofing-improve-e-mail-reliability&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.spfwizard.net/&quot;&gt;SPF Wizard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/mscorp/safety/content/technologies/senderid/wizard/&quot;&gt;MS SPF Wizard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.shellhacks.com/en/Setting-Up-Reverse-DNS-PTR-Record&quot;&gt;Reverse DNS from command line&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/networking/dns/setting-reverse-dns&quot;&gt;Reverse DNS on Linode&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.itworld.com/article/2833006/networking/how-to-setup-reverse-dns-and-ptr-records.html&quot;&gt;Useful article on reverse DNS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 03 Jun 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/06/spf-records/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/06/spf-records/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress Class Autoloader</title>
        <description>&lt;p&gt;Assuming that classes have been saved in individual files, according to WordPress best practice guidelines:
The file &lt;code class=&quot;highlighter-rouge&quot;&gt;/classes/my-unique-class.php&lt;/code&gt; contains &lt;code class=&quot;highlighter-rouge&quot;&gt;My_Unique_Class()&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function my_class_autoloader( $classname ) {

  // Build a filename that matches the correct protocol
  ------------------------------------------------------------------------------
  $classfile = sprintf( '%s/classes/class-%s.php',
  get_template_directory(),
  str_replace( '_', '-', strtolower( $classname ) )
  );

  if ( file_exists( $classfile ) ) include_once( $classfile );

}

// This function &quot;creates a queue of autoload functions, and runs through each of them in the order they are defined.&quot;
// -----------------------------------------------------------------------------
spl_autoload_register( 'my_class_autoloader' );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 29 Apr 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/04/wp-class-autoloader/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/04/wp-class-autoloader/</guid>
      </item>
      
    
      
      <item>
        <title>An Array of Post IDs from WP_Query</title>
        <description>&lt;p&gt;Return an array of Post IDs from a WordPress &lt;code class=&quot;highlighter-rouge&quot;&gt;WP_Query&lt;/code&gt; object - which can then be used to set up data from the _postmeta table.&lt;/p&gt;

&lt;p&gt;By having the query only return IDs, it is quicker and more efficient - but I constantly forget how to set it up.&lt;/p&gt;

&lt;p&gt;Note: There’s no loop to set up, you get the array from the object’s posts property: &lt;code class=&quot;highlighter-rouge&quot;&gt;$query_object-&amp;gt;posts&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;wpquery&quot;&gt;WP_Query&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/**
 * Return an array of post IDs
 *
 * Build a more efficient query by only returning an array of post IDs.
 *
 * @author David Egan
 * @return array Array of post IDs
 * @see http://codex.wordpress.org/Class_Reference/WP_Query#Return_Fields_Parameter
 */
function carawebs_student_questionnaire_results(){

  $args = array(
    'post_type'     =&amp;gt; 'questionnaire-result',
    'post_status'   =&amp;gt; 'publish',
    'fields'        =&amp;gt; 'ids',
    'meta_query'    =&amp;gt; array(
      array(
        'key'        =&amp;gt; 'user_type',
        'value'      =&amp;gt; 'student',
        'compare'    =&amp;gt; '=',
        'type'       =&amp;gt; 'CHAR',
      ),
    ),
  );

  // The Query
  $result_query = new WP_Query( $args );

  $ID_array = $result_query-&amp;gt;posts;

  // Restore original Post Data
  wp_reset_postdata();

  return $ID_array;

}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://generatewp.com/wp_query/&quot;&gt;Handy Query generator&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://codex.wordpress.org/Class_Reference/WP_Query#Return_Fields_Parameter&quot;&gt;WP Codex&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 21 Apr 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/04/wp-query-ids/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/04/wp-query-ids/</guid>
      </item>
      
    
      
      <item>
        <title>Incremental Timestamped Local Backup</title>
        <description>&lt;p&gt;This script creates a backup at regular intervals - you can backup every minute if necessary.&lt;/p&gt;

&lt;p&gt;The backup is incremental, so very efficient in terms of space and system resources.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;date &lt;span class=&quot;s2&quot;&gt;&quot;+%Y-%m-%d-%H:%M:%S&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
rsync -aP --link-dest&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Backups/current /home/david/Documents &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Backups/back-&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt;
rm -f &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Backups/current
ln -s back-&lt;span class=&quot;nv&quot;&gt;$date&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/Backups/current

&lt;span class=&quot;c&quot;&gt;# After running:&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;david@david-desktop:~/Backups$ &lt;/span&gt;ls -la
total 28
drwxrwxr-x   5 david david  4096 Jun 26 17:39 .
drwxr-xr-x 149 david david 12288 Jun 27 09:56 ..
drwxr-xr-x   3 root  root   4096 Jun 26 17:39 back-2015-06-26-17_39_06
drwxr-xr-x   3 root  root   4096 Jun 26 17:39 back-2015-06-26-17_39_25
drwxr-xr-x   3 root  root   4096 Jun 26 17:39 back-2015-06-26-17_39_36
lrwxrwxrwx   1 root  root     24 Jun 26 17:39 current -&amp;gt; back-2015-06-26-17_39_36&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;This script is based on &lt;a href=&quot;https://blog.interlinked.org/tutorials/rsync_time_machine.html&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Apr 2015 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2015/04/incremental-timestamped-backups/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/04/incremental-timestamped-backups/</guid>
      </item>
      
    
      
      <item>
        <title>Node, NVM &amp; NPM on Ubuntu 14.04</title>
        <description>&lt;p&gt;Guidelines on installing Node.js and
npm using Node Version Manager(NVM) in Ubuntu 14.04.&lt;/p&gt;

&lt;p&gt;This method will avoid EACCES errors when trying to install npm or npm packages. It will allow the use of &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install&lt;/code&gt; without sudo privileges on project directories.&lt;/p&gt;

&lt;h2 id=&quot;what-is-nodejs&quot;&gt;What is Node.js?&lt;/h2&gt;
&lt;p&gt;Node.js provides a way of running JavaScript on the server-side.&lt;/p&gt;

&lt;h2 id=&quot;what-is-npm&quot;&gt;What is NPM?&lt;/h2&gt;
&lt;p&gt;The package manager for Node.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An online repository for the publishing of open-source Node.js
projects&lt;/li&gt;
  &lt;li&gt;A command-line utility for interacting with this repository that aids in package installation, version management,
and dependency management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using npm, node packages can be installed from the repository
using a single line of command. e.g.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install async&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Another use for npm is dependency management. When you have a node project with a package.json file, you can run &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install&lt;/code&gt; from the
project root and npm will install all the dependencies listed in the package.json.&lt;/p&gt;

&lt;h2 id=&quot;version-management-installing-nvm&quot;&gt;Version Management: Installing NVM:&lt;/h2&gt;

&lt;p&gt;Before following the steps below to install node/npm, you should first make sure that there are no versions of node/npm already installed on your system. This can be done with the following lines of code:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;which node
which npm
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If there is no output after either of the above, then that respective package is not present on your system.&lt;/p&gt;

&lt;p&gt;Once this is complete, enter:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install build-essential libssl-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Once these prerequisite packages are installed you can install NVM with
with the command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You may now have to restart your terminal. Once you’ve done this, run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;source ~/.profile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This allows the current BASH profile to be reloaded, without logging out and back in again.&lt;/p&gt;

&lt;h2 id=&quot;installing-node&quot;&gt;Installing Node:&lt;/h2&gt;
&lt;p&gt;You can then view which versions of Node.js are available for installation with the command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvm ls-remote

&lt;span class=&quot;c&quot;&gt;#You can install the relevant version by entering:&lt;/span&gt;

nvm install 0.11.14

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

&lt;p&gt;NPM should be installed by default along with Node.js. You should now
be able to install packages without being required to use the sudo command.&lt;/p&gt;

&lt;p&gt;You can set a default version of Node to be used by the setting the alias
“default”. This is important, otherwise node isn’t recognised in a new shell:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nvm alias default 0.11.14&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This allows you to revert to a different version of Node if the current
version is incompatible with an particular application. Each version of
Node will keep track of its own packages. You can also install a package
globally, which will make it available to all projects using the same
version of Node, by adding the -g tag. e.g.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install -g grunt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Installing globally will let you run the commands from the command line,
but you’ll have to link the package into your local sphere to require
it from within a program. eg.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;npm link grunt&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/&quot;&gt;NPM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/npm&quot;&gt;NPM Packages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/creationix/nvm&quot;&gt;NVM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/creationix/nvm/issues/394&quot;&gt;Ubuntu Specific Issues, NVM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-an-ubuntu-14-04-server&quot;&gt;Step by step guide on installing Node.js by means of NVM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/16151018/npm-throws-error-without-sudo&quot;&gt;Why consider permissions during node installation?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/joyent/node/issues/3911&quot;&gt;Node/Ubuntu issue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://codetheory.in/using-node-version-manager-nvm-to-manage-multiple-node-js-versions/&quot;&gt;Using NVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 04 Mar 2015 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/03/setup-nodejs-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/03/setup-nodejs-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Update WordPress User Meta</title>
        <description>&lt;p&gt;#Build an Array
The objective is to create a two-dimensional array that holds information about user progress - in this case, when a user finishes a workbook, information is stored in a ‘completed_workbooks’ field.&lt;/p&gt;

&lt;h2 id=&quot;update-user-meta-function&quot;&gt;Update User Meta Function&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/**
*
* Update usermeta when a student completes a workbook.
*
* @param int $student_ID Student user ID
* @param int $workbook_ID Workbook(CPT) post ID
* @param int $stage Student's current stage
* @param int $workbook_total_stages Number of stages
* @param string $supervisor_name
* @param string $coord_name
* @param string $company_name
*
*
*/
function carawebs_finished_workbook (
  $student_ID,
  $workbook_ID,
  $stage,
  $workbook_total_stages,
  $supervisor_name,
  $coord_name,
  $company_name
  ){

  if ( $stage === $workbook_total_stages + 1 ) {

    // The student has completed the current workbook
    // -------------------------------------------------------------------------
    $date = date(&quot;F j, Y, g:i a&quot;);

    $existing_completed_meta = get_user_meta( $student_ID, 'completed_workbooks', true );

    if ( $existing_completed_meta ){

      // Previous workbooks have been completed
      // -----------------------------------------------------------------------

      $new_data = array (
          'workbook_ID'       =&amp;gt; $workbook_ID,
          'supervisor_name'   =&amp;gt; $supervisor_name,
          'coordinator_name'  =&amp;gt; $coord_name,
          'company_name'      =&amp;gt; $company_name,
          'date_completed'    =&amp;gt; $date
      );

      $existing_completed_meta[&quot;workbook_ID_$workbook_ID&quot;] = $new_data;

      update_user_meta( $student_ID, 'completed_workbooks', $existing_completed_meta );


    } else {

      // First workbook completed - add 'completed_workbooks' array
      // -----------------------------------------------------------------------

      $completed_meta = array(
        &quot;workbook_ID_$workbook_ID&quot;  =&amp;gt; array (
          'workbook_ID'       =&amp;gt; $workbook_ID,
          'supervisor_name'   =&amp;gt; $supervisor_name,
          'coordinator_name'  =&amp;gt; $coord_name,
          'company_name'      =&amp;gt; $company_name,
          'date_completed'    =&amp;gt; $date
        )
      );

      update_user_meta( $student_ID, 'completed_workbooks', $completed_meta );

    }

  }

}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;the-resulting-array&quot;&gt;The Resulting Array&lt;/h2&gt;
&lt;p&gt;The resulting array looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;array(2) {
  [&quot;workbook_ID_14&quot;]=&amp;gt;
  array(6) {
    [&quot;workbook_ID&quot;]=&amp;gt;
    string(2) &quot;14&quot;
    [&quot;supervisor_name&quot;]=&amp;gt;
    string(14) &quot;Clark Griswold&quot;
    [&quot;coordinator_name&quot;]=&amp;gt;
    string(10) &quot;David Egan&quot;
    [&quot;company_name&quot;]=&amp;gt;
    string(8) &quot;ACME Ltd&quot;
    [&quot;date_completed&quot;]=&amp;gt;
    string(25) &quot;February 8, 2015, 3:50 pm&quot;
  }
  [&quot;workbook_ID_13&quot;]=&amp;gt;
  array(6) {
    [&quot;workbook_ID&quot;]=&amp;gt;
    string(2) &quot;13&quot;
    [&quot;supervisor_name&quot;]=&amp;gt;
    string(14) &quot;Clark Griswold&quot;
    [&quot;coordinator_name&quot;]=&amp;gt;
    string(10) &quot;David Egan&quot;
    [&quot;company_name&quot;]=&amp;gt;
    string(8) &quot;ACME Ltd&quot;
    [&quot;date_completed&quot;]=&amp;gt;
    string(25) &quot;February 8, 2015, 3:51 pm&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;retrieve-data&quot;&gt;Retrieve Data&lt;/h2&gt;
&lt;p&gt;To retrieve the data:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;$completed_workbooks = get_user_meta( $student_ID, 'completed_workbooks', true );

// Access data for each workbook:

  $supervisor_name  = $completed_workbooks[&quot;workbook_ID_$workbook_ID&quot;]['supervisor_name'];&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sun, 08 Feb 2015 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2015/02/update-user-meta/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2015/02/update-user-meta/</guid>
      </item>
      
    
      
      <item>
        <title>SSH Notes</title>
        <description>&lt;p&gt;Paired SSH keys provide a secure way of linking two computers - e.g. a remote server and a local development machine.&lt;/p&gt;

&lt;h2 id=&quot;local&quot;&gt;Local&lt;/h2&gt;
&lt;p&gt;You need a locally generated public-private key pair. If you already have this on your local machine, skip this step - you can use the existing public key.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For normal usage, you should add a passphrase to the SSH key. If the machine is a laptop, consider a strong passphrase, held in an encrypted password manager like keepass.&lt;/p&gt;

&lt;p&gt;For automated processes (like backup scripts that need SSH connection), you can’t use a passphrase. You can however restrict the access for this kind of key - for example, you can &lt;a href=&quot;/linux/backup/rsync/2015/06/17/secure-rsync-between-servers/&quot;&gt;restrict the commands that can be run on the connection&lt;/a&gt; by editing the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.ssh/authorized_keys&lt;/code&gt; file on the remote machine.&lt;/p&gt;

&lt;p&gt;Copy the public key to the server. If using a service like GitHub or Bitbucket, you can paste the contents of the key in the appropriate window.&lt;/p&gt;

&lt;h2 id=&quot;ssh-copy-id&quot;&gt;ssh-copy-id&lt;/h2&gt;
&lt;p&gt;To copy to a self-managed server, you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;ssh-copy-id&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;ssh-copy-id is a script that uses ssh to  log  into  a  remote  machine (presumably  using  a login password, so password authentication should be enabled, unless you’ve done some clever use of multiple identities)&lt;/p&gt;

  &lt;p&gt;It also changes the permissions of the remote user’s home, ~/.ssh,  and ~/.ssh/authorized_keys   to   remove  group  writability  (which  would otherwise  prevent  you  from  logging  in,  if  the  remote  sshd  has StrictModes set in its configuration).&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;http://manpages.ubuntu.com/manpages/lucid/man1/ssh-copy-id.1.html&quot;&gt;http://manpages.ubuntu.com/manpages/lucid/man1/ssh-copy-id.1.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-copy-id daviduser@123.45.56.78&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you’re accessing SSH over a non-standard port:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh-copy-id -p 1234 daviduser@123.45.56.78&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;locked-down-password-connection&quot;&gt;Locked Down Password Connection&lt;/h2&gt;
&lt;p&gt;Passing the public key to the remote server requires a one-time password authenticated connection. If you have password authentication turned off, you’ll need to temporarily enable it to allow the key transfer. Once you’ve done this, check the connection works and then disable password authentication again.&lt;/p&gt;

&lt;p&gt;Turning off password authentication forces all connections to be made via SSH key pairs. This is very secure, since the SSH key is to all intents and purposes unbreakable - unless someone gets hold of the machine holding your private key.&lt;/p&gt;

&lt;p&gt;To temporarily enable password authentication:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Open the SSH config file for editing&lt;/span&gt;
sudo nano /etc/ssh/sshd_config

&lt;span class=&quot;c&quot;&gt;# Amend password Authentication&lt;/span&gt;
PasswordAuthentication yes&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Reload SSH:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo reload ssh&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Change the setting back when you’re finished and don’t forget to reload SSH.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;emergency&quot;&gt;Emergency&lt;/h2&gt;
&lt;p&gt;If you lose a machine that is connected via SSH key-pair to a server, remove the relevant key in the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.ssh/authorized_keys&lt;/code&gt; file of the remote server.&lt;/p&gt;

&lt;p&gt;Be prepared: keep a note of all servers connected via SSH key-pair, and keep a note of the local machine hostname to allow easy searching in the &lt;code class=&quot;highlighter-rouge&quot;&gt;authorized_keys&lt;/code&gt; file in the case of multiple entries. e.g.:&lt;/p&gt;

&lt;p&gt;Main Laptop: hostname: David-Gazelle&lt;br /&gt;
SSH Keys Connected:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Personal Github account&lt;/li&gt;
  &lt;li&gt;Company Bitbucket account&lt;/li&gt;
  &lt;li&gt;Server, plato&lt;/li&gt;
  &lt;li&gt;Server, archimedes&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 31 Dec 2014 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/12/ssh-notes/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/12/ssh-notes/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up restricted SFTP Access Using OpenSSH</title>
        <description>&lt;p&gt;#Set Up restricted SFTP Access
You can use OpenSSH to allow users to have restricted SFTP access to your filesystem.&lt;/p&gt;

&lt;p&gt;This guide is for OpenSSH_6.6.1p1 Ubuntu-2ubuntu2 running on Ubuntu Server 14.04.1 LTS.&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-new-user&quot;&gt;Set Up a New User&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Create a new user&lt;/span&gt;
useradd guest-user

&lt;span class=&quot;c&quot;&gt;# Set a password&lt;/span&gt;
passwd guest-user

&lt;span class=&quot;c&quot;&gt;# Set the home directory for the new user to the target site directory&lt;/span&gt;
usermod -d /var/www/yoursite.com/public_html/subsite guest-user
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;block-ssh-access&quot;&gt;Block SSH Access&lt;/h2&gt;
&lt;p&gt;Prevent the user from accessing the server’s shell - so they can’t access by SSH:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo usermod -s /bin/false guest-user
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;configure-ssh&quot;&gt;Configure SSH&lt;/h2&gt;
&lt;p&gt;First make a backup of sshd_config. Then edit the SSH config file:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_bak
sudo nano /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;First set the sftp subsystem:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#Subsystem sftp /usr/lib/openssh/sftp-server&lt;/span&gt;
Subsystem sftp internal-sftp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then append this stanza to the end of the file:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Match user guest-user
ChrootDirectory /var/www/yoursite.com/public_html/subsite
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Note that I had trouble making this work by matching Groups - which would obviously be a more efficient way of setting this up.&lt;/p&gt;

&lt;p&gt;Ctrl + o to save, Ctrl + x to exit.&lt;/p&gt;

&lt;p&gt;Restart SSH - use THIS:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo service ssh restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;DON’T use this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo /etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you try to connect via SSH for the new user, you’ll see this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;david@david-desktop:~$ ssh -p 1234 guest-user@123.45.67.890
guest-user@123.45.67.890's password:
Could not chdir to home directory /var/www/yoursite.com/public_html/subsite: No such file or directory
This service allows sftp connections only.
Connection to 123.45.67.890 closed.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Remember to set the correct port for SSH access when accessing via SFTP.&lt;/p&gt;

&lt;h2 id=&quot;external-resources&quot;&gt;External Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikibooks.org/wiki/OpenSSH/Cookbook/SFTP&quot;&gt;SFTP Chapter, Open SSH Cookbook&lt;/a&gt; - an excellent free online book that outlines how to configure SSH.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/lts/serverguide/openssh-server.html&quot;&gt;Ubuntu Guide to OpenSSH Server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://serverfault.com/questions/392601/how-to-add-user-with-sftp-ftp-access-to-var-www-html-website-abc-folder-on-a&quot;&gt;http://serverfault.com/questions/392601/how-to-add-user-with-sftp-ftp-access-to-var-www-html-website-abc-folder-on-a&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.fullybaked.co.uk/articles/chroot-ssh-ftp-users-to-home-directory&quot;&gt;http://www.fullybaked.co.uk/articles/chroot-ssh-ftp-users-to-home-directory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 31 Dec 2014 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/12/restricted-sftp-access/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/12/restricted-sftp-access/</guid>
      </item>
      
    
      
      <item>
        <title>Responsive Images in IE 8</title>
        <description>&lt;p&gt;Images can be made responsive, while retaining aspect ratio with:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;nc&quot;&gt;.img-responsive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;However IE8 doesn’t like max-width: 100%.&lt;/p&gt;

&lt;p&gt;One way to deal with this is to put IE styles into a &lt;code class=&quot;highlighter-rouge&quot;&gt;@media&lt;/code&gt; block, so that they are only applied to certain versions of IE.&lt;/p&gt;

&lt;p&gt;This is hacky - most browsers don’t parse the code as they recognise the &lt;code class=&quot;highlighter-rouge&quot;&gt;\&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;/code&gt; characters.&lt;/p&gt;

&lt;p&gt;This code block is only applied by IE 6, 7 &amp;amp; 8:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Add a different img width for IE 8 and lower */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screen&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screen&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;img-responsive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;auto&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This doesn’t work in LESS, but we can hack the hack by declaring a LESS variable and using that:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-less&quot;&gt;@iehack: \0screen\,screen\9;

@media @iehack {
    .img-responsive {
        width: auto;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It may be a bit hacky, but it gets the job done. Hopefully it won’t be needed for much longer as these old browsers drop off the face of the internet.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://keithclark.co.uk/articles/moving-ie-specific-css-into-media-blocks/&quot;&gt;IE Specific code blocks in media queries&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/17699588/viewport-media-and-less/17699986#17699986&quot;&gt;http://stackoverflow.com/questions/17699588/viewport-media-and-less/17699986#17699986&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 06 Nov 2014 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/11/ie8-responsive-image/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/11/ie8-responsive-image/</guid>
      </item>
      
    
      
      <item>
        <title>Quick Build WordPress &amp; Roots</title>
        <description>&lt;p&gt;This BASH script was written to automate the deployment of WordPress &amp;amp; Roots on a local development server (Ubuntu 14.04). It could easily be adapted for use in a public-facing server.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/Carawebs/bash-deploy-wp-roots&quot;&gt;Clone the project&lt;/a&gt; on GitHub - pull requests welcome.&lt;/p&gt;

&lt;p&gt;Save the script as &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/local/bin/roots-spin&lt;/code&gt; and make executable:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chmod +x /usr/local/bin/roots-spin&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This script:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Creates a new directory for a WordPress site in /var/www.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Creates a new WordPress test site, with a fresh database.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Downloads, renames and activates the Roots theme.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Sets up a new GitHub repo for the new theme (GitHub personal token needs to be in place)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Downloads &amp;amp; activates the &quot;Soil&quot; plugin.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Installs node &amp;amp; bower dependencies by running npm install.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Requires WP-CLI: http://wp-cli.org/&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Ubuntu: save this script as /usr/local/bin/roots-spin&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# - Make it executable, then you can invoke it by typing &quot;roots-spin&quot; in the terminal.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# NOTE: depending on your node setup, you may need to amend the setup_node () function in this script (see inline comments).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Set up directory, download wp core&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Please enter the name of the new wp directory:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read  &lt;/span&gt;wp_dir
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www
sudo mkdir &lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;
sudo chown -R &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;
wp core download
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;The new directory has been created at /var/www/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;It is owned by &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;WordPress core has been downloaded&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Build new database&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;This script will create a local database with a new user. Username &amp;amp; password based on DB name, but this is OK because we're working LOCALLY.&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Enter the name of the new database:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read  &lt;/span&gt;db_name

&lt;span class=&quot;c&quot;&gt;# Set up variables&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Username is just the &quot;salted&quot; db name. For publicly accessible databases, make this more secure.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;newuser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;
newuser+&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;_user
&lt;span class=&quot;c&quot;&gt;# Password is just the &quot;salted&quot; db name. Adjust this for better passwords - require user input.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;newpassword&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;
newpassword+&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;_pass1234

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Enter the MySQL root password:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read  &lt;/span&gt;rootpassword

&lt;span class=&quot;nv&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;create database &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;GRANT ALL PRIVILEGES ON &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.* TO &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newuser&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;@localhost IDENTIFIED BY '&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newpassword&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;';FLUSH PRIVILEGES;&quot;&lt;/span&gt;
mysql -u root -p&lt;span class=&quot;nv&quot;&gt;$rootpassword&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; !&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Note: &quot;0&quot; is the return from successful completion of the previous operation in BASH.&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[Error]: Database creation failed&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ---------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Set up wp-config.php. These are WP-CLI commands.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ---------------------------&lt;/span&gt;

wp core config --dbname&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt; --dbuser&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newuser&lt;/span&gt; --dbpass&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newpassword&lt;/span&gt; --dbhost&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;localhost

&lt;span class=&quot;c&quot;&gt;# ---------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Install WordPress. WP-CLI.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ---------------------------&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Enter a strong password - your database may be exported to a publicly accessible server, so please set a strong password.&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;strong_password

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Enter a username. NOT 'ADMIN'!&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;username

wp core install --url&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;http://localhost/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt; --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Basic Test Site&quot;&lt;/span&gt; --admin_user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt; --admin_password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$strong_password&lt;/span&gt; --admin_email&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;you@yourweb.com


 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; WordPress has been installed successfully: http://localhost/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; DB Info: &quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; DB Name: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dbname&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; DB User: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newuser&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; DB Pass: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newpassword&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; WordPress User details:&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; WP username: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; WP password: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$strong_password&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ---------------------------------&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Set Up Roots Theme&lt;/span&gt;

setup_theme &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes
git clone https://github.com/roots/roots.git
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Choose a name for the new theme:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;themename
cp -r /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/roots /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Change first line of style.css to avoid confusion&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;themeline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Theme Name: &quot;&lt;/span&gt;
themeline+&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;

awk -v &lt;span class=&quot;nv&quot;&gt;stylename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$themeline&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{ if (NR == 1) print stylename; else print $0}'&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/style.css &amp;gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/stylemod.css
sudo cp /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/stylemod.css /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/style.css
rm -rf /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/stylemod.css

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;-------------------------------------------------------------------------&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;The first line of style.css has been amended&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;to reflect your theme name - don&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\'&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;t forget to amend the rest of this file.&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;NB: this script has appended a line to wp-config.php to set up the Roots development environment.&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;-------------------------------------------------------------------------&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Backup original config file&lt;/span&gt;
cp /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config.php /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config.bak.php

&lt;span class=&quot;nv&quot;&gt;newline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/* Define the Roots Environment */&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;define('WP_ENV', 'development');&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
awk -v &lt;span class=&quot;nv&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newline&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'NR==3{print insert}1'&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config.php &amp;gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config-temp.php

cp /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config-temp.php /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-config.php

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

install_soil &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/plugins
git clone https://github.com/roots/soil.git
wp plugin activate soil
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

setup_node &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Note: npm runs without sudo if node has been installed on your system by the nvm method:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# https://github.com/creationix/nvm (recommended!)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Otherwise, the npm install command should run as sudo, followed by bower install.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# For this case comment out line 133 &amp;amp; enable lines 134 &amp;amp; 135)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Or move to the theme directory after installation is complete and run sudo npm install followed by bower install&lt;/span&gt;
npm install
&lt;span class=&quot;c&quot;&gt;# sudo npm install&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# bower install&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

run_grunt &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;
grunt build
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

activate_theme &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;
wp theme activate &lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

setup_repo &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# remove existing git repo&lt;/span&gt;
sudo rm -rf /var/www/&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;/wp-content/themes/&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;/.git
git init

&lt;span class=&quot;nv&quot;&gt;repo_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;

  &lt;span class=&quot;nv&quot;&gt;dir_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;basename &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;invalid_credentials&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$repo_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;  Repo name (hit enter to use '&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dir_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;')?&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;repo_name
  &lt;span class=&quot;k&quot;&gt;fi

  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$repo_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;repo_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dir_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fi

  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;git config github.user&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;  Could not find username, run 'git config --global github.user &amp;lt;username&amp;gt;'&quot;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;invalid_credentials&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1
  &lt;span class=&quot;k&quot;&gt;fi

  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;git config github.token&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;  Could not find token, run 'git config --global github.token &amp;lt;token&amp;gt;'&quot;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;invalid_credentials&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1
  &lt;span class=&quot;k&quot;&gt;fi

  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$invalid_credentials&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; -eq &lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then
    return &lt;/span&gt;1
  &lt;span class=&quot;k&quot;&gt;fi

  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -n &lt;span class=&quot;s2&quot;&gt;&quot;  Creating Github repository '&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$repo_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;' ...&quot;&lt;/span&gt;
  curl -u &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$token&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; https://api.github.com/user/repos -d &lt;span class=&quot;s1&quot;&gt;'{&quot;name&quot;:&quot;'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$repo_name&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&quot;}'&lt;/span&gt; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; done.&quot;&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -n &lt;span class=&quot;s2&quot;&gt;&quot;  Pushing local code to remote ...&quot;&lt;/span&gt;
  git remote add origin git@github.com:&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$repo_name&lt;/span&gt;.git &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
  git push -u origin master &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
  git add -A
  git commit -m &lt;span class=&quot;s2&quot;&gt;&quot;First Commit&quot;&lt;/span&gt;
  git push origin master
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; done.&quot;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you want to set up the Roots 7 Starter theme? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; setup_theme;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Set up a new GitHub repo for &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; setup_repo;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you want to install and activate the Roots &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Soil&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; plugin? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; install_soil;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you want to go to the &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; theme and install node dependencies? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; setup_node;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Do you want to activate the &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$themename&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; theme? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; activate_theme;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

	&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; -p &lt;span class=&quot;s2&quot;&gt;&quot;Move to the theme directory and run the grunt build task? [y/N]&quot;&lt;/span&gt; yn
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$yn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Yy]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; run_grunt;;
	&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Nn]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Please answer yes or no.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;sitelocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Access your new site: http://localhost/&quot;&lt;/span&gt;
sitelocation+&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$wp_dir&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------------&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;Finished!&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$sitelocation&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------------&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Sun, 26 Oct 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/10/deploy-wordpress-roots-bash-script/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/10/deploy-wordpress-roots-bash-script/</guid>
      </item>
      
    
      
      <item>
        <title>Testing Internet Explorer in Ubuntu Using Virtual Machines</title>
        <description>&lt;p&gt;Cross-browser testing of Internet Explorer in a Ubuntu 14.04 development environment - using VirtualBox and Microsoft VM.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/generated/IE-on-ubuntu-1313x908-05d9e2.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;virtualbox&quot;&gt;VirtualBox&lt;/h2&gt;
&lt;p&gt;VirtualBox is a system emulator that can run a guest operating system in a window of the host operating system.&lt;/p&gt;

&lt;p&gt;This allows us to test websites on a range of platforms without dual-booting or running a dedicated test-machine.&lt;/p&gt;

&lt;p&gt;There are two versions of Virtualbox available for Ubuntu. Both open-source, one is packaged by Ubuntu, the other provided by VirtualBox. Either download Virtualbox for Linux and build it yourself, or access Virtualbox in the Ubuntu software manager:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/wiki/Linux_Downloads&quot;&gt;Download VirtualBox for Linux hosts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Search for “virtualbox” in Ubuntu software centre &amp;amp; install as usual&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;build-a-windows-vm&quot;&gt;Build a Windows VM&lt;/h2&gt;
&lt;p&gt;Go to &lt;a href=&quot;https://www.modern.ie/en-us/virtualization-tools#downloads&quot;&gt;modern.ie&lt;/a&gt; and create the build you need. You can select an OS and a version of Internet Explorer.&lt;/p&gt;

&lt;p&gt;Select “VirtualBox for Linux” as the Platform, and select “Download your Virtual Machine”.&lt;/p&gt;

&lt;p&gt;Click “Batch File Download” - this opens a txt file with a list of URLS. The URLS are the files required to build the Windows VM.&lt;/p&gt;

&lt;p&gt;Create a new directory for the VM, and move into the directory:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd
mkdir win7IE11
cd win7IE11
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Run wget -i against the URL of the batch txt file to download all the necessary files:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;wget -i https://az412801.vo.msecnd.net/vhd/VMBuild_20131127/VirtualBox/IE11_Win7/Linux/IE11.Win7.ForLinuxVirtualBox.txt
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Go and have a cup of tea, cos it’s gonna take a while…&lt;/p&gt;

&lt;p&gt;Make the file executable…
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chmod +x IE11.Win7.ForLinuxVirtualBox.part1.sfx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To extract the files, you may need to install the following:
&lt;code class=&quot;highlighter-rouge&quot;&gt;apt-get install lib32stdc++6&lt;/code&gt;
See: &lt;a href=&quot;http://stackoverflow.com/questions/11471722/libstdc-so-6-cannot-open-shared-object-file-no-such-file-or-directory&quot;&gt;http://stackoverflow.com/questions/11471722/libstdc-so-6-cannot-open-shared-object-file-no-such-file-or-directory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run the .sfx file to build the VM:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;~/win7IE11/IE11.Win7.ForLinuxVirtualBox.part1.sfx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The VM files should be extracted to a &lt;code class=&quot;highlighter-rouge&quot;&gt;.ova&lt;/code&gt; file.&lt;/p&gt;

&lt;h2 id=&quot;import--use-the-vm&quot;&gt;Import &amp;amp; Use the VM&lt;/h2&gt;
&lt;p&gt;Open VirtualBox. Click “Import Appliance” in the menu bar, and navigate to the .ova file.&lt;/p&gt;

&lt;p&gt;VirtualBox will build the VM. To use it, open VirtualBox and launch the relevant VM.&lt;/p&gt;

&lt;h2 id=&quot;localhost&quot;&gt;Localhost&lt;/h2&gt;
&lt;p&gt;The local server can be accessed on the VM at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://10.0.2.2/&lt;/code&gt;. However, my out-of-the box settings give me access to localhost files, but built in references to stylesheets etc are broken - since “localhost” is referenced.&lt;/p&gt;

&lt;p&gt;This is fixed by amending &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\windows\system32\drivers\etc\hosts&lt;/code&gt; - just add the line &lt;code class=&quot;highlighter-rouge&quot;&gt;10.0.2.2 localhost&lt;/code&gt;. To open this as a Windows admin, open notepad as administrator (by right clicking) and then navigate to the hosts file.&lt;/p&gt;

&lt;h2 id=&quot;useful-resources&quot;&gt;Useful Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/VirtualBox&quot;&gt;https://help.ubuntu.com/community/VirtualBox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.ubuntu.com/community/VirtualBox/Installation&quot;&gt;VirtualBox installation in Ubuntu&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;VirtualBox home page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.modern.ie/en-us/virtualization-tools#downloads&quot;&gt;Windows/Internet Explorer VM Downloads&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.sitepoint.com/virtual-machine-browser-testing-modern-ie/&quot;&gt;This article&lt;/a&gt; focuses on using VirtualBox/Windows VMs for testing on Macs - but is still relevant for Ubuntu users.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 25 Oct 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/10/testing-ie-on-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/10/testing-ie-on-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Bootstrap Carousel with Indicators Navigation for WordPress</title>
        <description>&lt;p&gt;A Bootstrap carousel with dual indicators/controls for WordPress. Populated by ACF “relationship” field.&lt;/p&gt;

&lt;h2 id=&quot;indicators&quot;&gt;Indicators&lt;/h2&gt;
&lt;p&gt;This carousel has two sets of indicators - a set of numbers, and an un-numbered “standard” set of indicators.&lt;/p&gt;

&lt;p&gt;It needs a bit of work to have the active class attached properly to the second set of indicators.&lt;/p&gt;

&lt;p&gt;This is achieved by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Giving a unique class name to these indicators (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;class=&quot;no-numbers&quot;&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Testing the contained list items &lt;code class=&quot;highlighter-rouge&quot;&gt;data-slide-to=&lt;/code&gt; against the currently displayed item&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;building-the-carousels---acf&quot;&gt;Building the Carousels - ACF&lt;/h2&gt;
&lt;p&gt;The carousel content is built from an ACF “relationship” field, which is used to create a custom WordPress loop. In this case, the relationship field is used to create a loop of “report” custom post types.&lt;/p&gt;

&lt;h2 id=&quot;build-the-carousel&quot;&gt;Build the Carousel&lt;/h2&gt;
&lt;p&gt;This PHP function builds the carousel. The code could be added to the theme &lt;strong&gt;custom.php&lt;/strong&gt; file. I usually keep custom loops in a unique file for ease of editing, and require_once this file in &lt;strong&gt;functions.php&lt;/strong&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*==============================================================================
  Case Studies for Services Mobile
  ============================================================================*/
function carawebs_reports_mobile() {

    $relationship_field = 'related'; // This could be passed into the function

    $posts = get_field($relationship_field);

    if ($posts) {
      ?&amp;gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mobile-reports-carousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel slide&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-ride=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Indicators --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ol&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-indicators numbered list-unstyled list-inline&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

          &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Start up a count
&lt;/span&gt;          &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$posts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&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;c1&quot;&gt;// Loop through the array
&lt;/span&gt;
            &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#mobile-reports-carousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide-to=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt; &lt;span class=&quot;o&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt;&lt;span class=&quot;o&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-count&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- output carousel index &amp;amp; total number of slides for debugging, set by jQuery function --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ol&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-indicators no-numbers&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

          &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$posts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#mobile-reports-carousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide-to=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$item_count&lt;/span&gt;&lt;span class=&quot;o&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-inner&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$number&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$posts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&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;c1&quot;&gt;// variable must be called $post (IMPORTANT)
&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;setup_postdata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item counter-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// custom function to bring in the 'medium' featured image
&lt;/span&gt;          &lt;span class=&quot;nx&quot;&gt;carawebs_featured_image&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'medium'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the_permalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;post_content&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the_content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// Another custom field - builds a ul of file downloads
&lt;/span&gt;          &lt;span class=&quot;nx&quot;&gt;carawebs_download_link_repeater&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$number&lt;/span&gt;&lt;span class=&quot;o&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Restore original Post Data
&lt;/span&gt;    &lt;span class=&quot;nx&quot;&gt;wp_reset_postdata&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;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This carousel needed to replace a more elaborate slider at small screen sizes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row report-downloads&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text-center&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Report Downloads&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php

        // This function returns 'true' for mobile phones
        if (carawebs_is_phone()=='true'){

          // If this is a mobile phone
          // --------------------------
          // #innovations--section-toggle &amp;amp; #innovation-content set up for collapse in /assets/js/_frontpage-toggles.js
          ?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;reports-mobile&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php carawebs_reports_mobile(); ?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php

        } else {

          // The device is NOT a phone
          // Hide at small screens using CSS - target #reports-desktop
          // --------------------------
          ?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;reports-desktop&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

              &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php carawebs_reports_desktop(); ?&amp;gt;&lt;/span&gt;

          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php

          // Add the mobile view stuff here to allow a mobile-type view on contracted desktops
          // ---------------------------
          ?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;reports-mobile-visible&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-xs-14 col-xs-offset-1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
              &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php carawebs_reports_mobile(); ?&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php

        }

      ?&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- /.report-downloads --&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The “check for phone” function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*==============================================================================
  Detect Phones
  ============================================================================*/
function carawebs_is_phone() {

	$useragent=$_SERVER['HTTP_USER_AGENT'];
	if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))
	return true;
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;See here for lioghtweight phone detection strings: &lt;a href=&quot;http://detectmobilebrowsers.com/&quot;&gt;http://detectmobilebrowsers.com/&lt;/a&gt;.
This might be a useful phone detecting class: &lt;a href=&quot;https://github.com/serbanghita/Mobile-Detect/&quot;&gt;https://github.com/serbanghita/Mobile-Detect/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the non-phone case, the relevant divs are shown/hidden by means of CSS.&lt;/p&gt;

&lt;h2 id=&quot;jquery&quot;&gt;jQuery&lt;/h2&gt;

&lt;p&gt;Controls are built into &lt;strong&gt;/js/_carousel.js&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Set up - give first items emphasis classes.
    Necessary because the slider is built dynamically
==============================================================================*/&lt;/span&gt;

   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#mobile-reports-carousel .carousel-indicators li:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#mobile-reports-carousel .carousel-indicators.no-numbers li:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Give active class to the first carousel item&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#mobile-reports-carousel .item:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Prevent auto play&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#mobile-reports-carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carousel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Listen to the 'slid carousel' event to trigger code after each slide change
==============================================================================*/&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#case-studies-carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'slid.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;c1&quot;&gt;// For debugging...&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//alert(&quot;We have SLID!!! Thank God it's working...&quot;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Useful variables&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// get current index the Bootstrap way...&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getItemIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.item.active'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// ...get the current index the jQuery way...&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;itemIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.item.active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jCurrentIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;itemIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// For debugging: needs a #carousel-count div in the markup&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Index: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jCurrentIndex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#carousel-count'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Using bs method, getItemIndex - see: https://github.com/twbs/bootstrap/issues/14215&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//$('.carousel-indicators.no-numbers [data-slide-to=' + currentIndex + ']').addClass('active');//&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Pure jQuery method - attach the active class to the indicator corresponding to the current item&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// -----------------------------------&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.carousel-indicators.no-numbers [data-slide-to='&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;jCurrentIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;']'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'active'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;mobile-swipe-support&quot;&gt;Mobile Swipe Support&lt;/h2&gt;
&lt;p&gt;For mobile swipe support, use the &lt;a href=&quot;https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/blob/master/jquery.touchSwipe.js&quot;&gt;touchSwipe jQuery plugin&lt;/a&gt;. This plugin is copyright (c) 2010 Matt Bryson and is dual licensed under the MIT or GPL Version 2 licenses.&lt;/p&gt;

&lt;h2 id=&quot;related-tutorials&quot;&gt;Related Tutorials&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://carawebs.com/dev-notes/bootstrap/wordpress/jquery/php/2014/07/05/bootstrap-carousel-wordpress/&quot;&gt;http://carawebs.com/dev-notes/bootstrap/wordpress/jquery/php/2014/07/05/bootstrap-carousel-wordpress/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 22 Oct 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/10/wordpress-bootstrap-carousel-with-indicators/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/10/wordpress-bootstrap-carousel-with-indicators/</guid>
      </item>
      
    
      
      <item>
        <title>Add Items to a WordPress Navigation ul</title>
        <description>&lt;p&gt;Add a button as the last item in a WordPress navigation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;  add_filter('wp_nav_menu_items','carawebs_payment_button', 10, 2);

function carawebs_payment_button($items, $args) {

  if (!is_admin() &lt;span class=&quot;err&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; $args-&amp;gt;theme_location == 'primary_navigation') {

  $items .= '&lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pay-button&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://#&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;button&amp;gt;&lt;/span&gt;Click&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;';



  }

  return $items;
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add a search form as the last item in a WordPress navigation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;  add_filter('wp_nav_menu_items','carawebs_payment_button', 10, 2);

function carawebs_payment_button($items, $args) {

  if (!is_admin() &lt;span class=&quot;err&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; $args-&amp;gt;theme_location == 'primary_navigation') {

  ob_start();
  get_search_form();
  $searchform = ob_get_contents();
  ob_end_clean();

  $items .= '&lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;search&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Search ' . $searchform . '&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;';

  }

  return $items;
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Wed, 08 Oct 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/10/add-items-to-wordpress-nav/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/10/add-items-to-wordpress-nav/</guid>
      </item>
      
    
      
      <item>
        <title>Securing a Ubuntu 14.04 Server</title>
        <description>&lt;p&gt;These guidelines assume a fresh install of Ubuntu 14.04.&lt;/p&gt;

&lt;h2 id=&quot;secure-ssh-access&quot;&gt;Secure SSH Access&lt;/h2&gt;
&lt;p&gt;The most important step is probably to change the default port for SSH.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change the default SSH port.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many brute force hacking attempts target the username “root” on port 22.&lt;/p&gt;

&lt;p&gt;Simply changing the port can reduce the number of malicious login attempts drastically.&lt;/p&gt;

&lt;p&gt;Change the SSH port number to something between 1025 and 65536. The Server’s SSH connections will then look to the new port number.&lt;/p&gt;

&lt;p&gt;In Ubuntu the SSH port is set in:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/ssh/sshd_config&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before going any further, backup the config file!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the config file and amend the port number (first uncommented line in the file):&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restart SSH to enable the changes:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;service ssh restart&lt;/code&gt; or&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/init.d/sshd restart&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;test-the-new-configuration&quot;&gt;TEST THE NEW CONFIGURATION&lt;/h2&gt;

&lt;p&gt;Keep your terminal open, and try to log in with a new terminal. In this way, if you can’t login you still have server access.&lt;/p&gt;

&lt;p&gt;Remember to specify the correct port number (see below).&lt;/p&gt;

&lt;h2 id=&quot;ssh-login---non-standard-port&quot;&gt;SSH Login - Non Standard Port&lt;/h2&gt;
&lt;p&gt;Assuming the SSH port is 1234.&lt;/p&gt;

&lt;p&gt;SSH login:
&lt;code class=&quot;highlighter-rouge&quot;&gt;ssh -p 1234 user@12.34.567.89&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Using scp:
&lt;code class=&quot;highlighter-rouge&quot;&gt;scp -P 1234 username@12.34.567.89:/path/file.txt&lt;/code&gt;
Note: uppercase P is necessary - lowercase p is an scp switch.&lt;/p&gt;

&lt;p&gt;Using rsync:
&lt;code class=&quot;highlighter-rouge&quot;&gt;rsync --progress -a -v -rz --checksum --delete -e &quot;ssh -p 1234&quot; _site/ user@12.34.567.89:/var/www/path/directory&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;root-login&quot;&gt;Root Login&lt;/h2&gt;
&lt;p&gt;Once the SSH port has been reset, prevent root login with password. Root will still be able to gain access by means of public SSH keys - which can be set up on your local machine.&lt;/p&gt;

&lt;p&gt;Amend the following block in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Authentication:&lt;/span&gt;
LoginGraceTime 120
&lt;span class=&quot;c&quot;&gt;# root can't log in via SSH &amp;amp; password - allows root login only with public key&lt;/span&gt;
PermitRootLogin without-password
StrictModes yes&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Alternatively, prevent root access altogether:
&lt;code class=&quot;highlighter-rouge&quot;&gt;PermitRootLogin no&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make sure you’ve created a new user with sudo privileges before doing this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After making changes to SSH configuration, restart SSH:
&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/init.d/sshd restart&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;set-up-a-firewall&quot;&gt;Set up a Firewall&lt;/h2&gt;

&lt;p&gt;Enter &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo iptables -L&lt;/code&gt;, will return an empty ruleset:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Chain INPUT &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;policy ACCEPT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
target     prot opt &lt;span class=&quot;nb&quot;&gt;source               &lt;/span&gt;destination

Chain FORWARD &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;policy ACCEPT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
target     prot opt &lt;span class=&quot;nb&quot;&gt;source               &lt;/span&gt;destination

Chain OUTPUT &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;policy ACCEPT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
target     prot opt &lt;span class=&quot;nb&quot;&gt;source               &lt;/span&gt;destination&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make a file for firewall rules:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/iptables.firewall.rules&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;…and add some rules:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;filter

&lt;span class=&quot;c&quot;&gt;#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0&lt;/span&gt;
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

&lt;span class=&quot;c&quot;&gt;#  Accept all established inbound connections&lt;/span&gt;
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

&lt;span class=&quot;c&quot;&gt;#  Allow all outbound traffic - you can modify this to only allow certain traffic&lt;/span&gt;
-A OUTPUT -j ACCEPT

&lt;span class=&quot;c&quot;&gt;#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).&lt;/span&gt;
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;#  Allow SSH connections&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  The -dport number should be the same port number you set in sshd_config&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
-A INPUT -p tcp -m state --state NEW --dport 1234 -j ACCEPT

&lt;span class=&quot;c&quot;&gt;#  Allow ping&lt;/span&gt;
-A INPUT -p icmp -j ACCEPT

&lt;span class=&quot;c&quot;&gt;#  Log iptables denied calls&lt;/span&gt;
-A INPUT -m limit --limit 5/min -j LOG --log-prefix &lt;span class=&quot;s2&quot;&gt;&quot;iptables denied: &quot;&lt;/span&gt; --log-level 7

&lt;span class=&quot;c&quot;&gt;#  Drop all other inbound - default deny unless explicitly allowed policy&lt;/span&gt;
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Activate rules:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo iptables-restore &amp;lt; /etc/iptables.firewall.rules&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/iptables.firewall.rules&lt;/code&gt; as necessary.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;check-you-still-have-ssh-access&quot;&gt;Check you Still Have SSH Access&lt;/h2&gt;
&lt;p&gt;The firewall rules set the port number for SSH access - this should correspond to the value set in &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/ssh/sshd_config&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Make sure!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While still logged in on one terminal, open a new terminal and check SSH connection is still functional.&lt;/p&gt;

&lt;h2 id=&quot;apply-firewall-rules-when-system-reboots&quot;&gt;Apply Firewall Rules When System Reboots&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/network/if-pre-up.d/firewall&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
/sbin/iptables-restore &amp;lt; /etc/iptables.firewall.rules&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Save, make executable:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chmod +x /etc/network/if-pre-up.d/firewall&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;fail2ban&quot;&gt;Fail2Ban&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Debian&quot;&gt;Fail2Ban Manual&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install fail2ban&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;View Fail2Ban configuration settings - &lt;em&gt;read only&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nano /etc/fail2ban/jail.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This file can be modified by package upgrades - thereby losing customisations - so to make changes, create a jail.local file.&lt;/p&gt;

&lt;p&gt;First copy the jail.conf:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make all amendments to jail.local.&lt;/p&gt;

&lt;p&gt;Default setting ignores traffic from the local machine: &lt;code class=&quot;highlighter-rouge&quot;&gt;ignoreip = 127.0.0.1/8&lt;/code&gt;. Additional IP addresses could be added here, by appending to the existing parameter, separating IP addresses with a space.&lt;/p&gt;

&lt;p&gt;You could add the local office IP address for example, to prevent accidental lockout.&lt;/p&gt;

&lt;p&gt;Check it’s running:
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client status&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;check-rules&quot;&gt;Check Rules&lt;/h2&gt;
&lt;p&gt;Enter &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo iptables -S&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Typical Output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 12345 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix &lt;span class=&quot;s2&quot;&gt;&quot;iptables denied: &quot;&lt;/span&gt; --log-level 7
-A INPUT -j DROP
-A FORWARD -j DROP
-A OUTPUT -j ACCEPT
-A fail2ban-ssh -j RETURN&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The –dport number on line 11 corresponds to the number set in firewall rules - SSH connections are accepted on that port.&lt;/p&gt;

&lt;p&gt;This means fail2ban port should change. Amend &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/fail2ban/jail.local&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ssh]

enabled  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# change the port from ssh to the proper value&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#port     = ssh&lt;/span&gt;
port   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 12345
filter   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; sshd
logpath  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /var/log/auth.log
maxretry &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 6&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once this change is made, reload fail2ban configuration:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client reload&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Because Fail2Ban sets the port as “ssh” bu default, it searches in the &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/services&lt;/code&gt; file and maps ssh to the named port.&lt;/p&gt;

&lt;p&gt;The port is set to 22 in this file by default. Adjusting this value would be another way of pointing Fail2Ban to the right port.&lt;/p&gt;

&lt;p&gt;See this &lt;a href=&quot;http://serverfault.com/questions/522191/fail2ban-iptables-having-port-22-and-fails-to-block-ssh-on-custom-port&quot;&gt;Server Fault&lt;/a&gt; question.&lt;/p&gt;

&lt;h2 id=&quot;handy-fail2ban-commands&quot;&gt;Handy Fail2Ban commands&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client start&lt;/code&gt; - starts the server and the jails&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client reload&lt;/code&gt; - reloads the configuration&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client reload &amp;lt;JAIL&amp;gt;&lt;/code&gt; -	reloads the jail &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;JAIL&amp;gt;&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client stop&lt;/code&gt; - stops all jails and terminate the server&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client status&lt;/code&gt; - gets the current status of the server&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client ping&lt;/code&gt; - tests if the server is alive&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo fail2ban-client help&lt;/code&gt; - return this output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More &lt;a href=&quot;http://www.fail2ban.org/wiki/index.php/Commands&quot;&gt;Fail2Ban commands&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-install-and-use-fail2ban-on-ubuntu-14-04&quot;&gt;Article on Setting up Fail2Ban&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/security/securing-your-server&quot;&gt;Securing a Linode Server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04&quot;&gt;Initial Server Setup, Ubuntu 14.04&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 25 Sep 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/09/securing-ubuntu-server/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/09/securing-ubuntu-server/</guid>
      </item>
      
    
      
      <item>
        <title>Bootstrap Modals</title>
        <description>&lt;p&gt;#Bootstrap Modals
Modals enable user triggered hide and display of additional HTML content.&lt;/p&gt;

&lt;p&gt;To set up a pure HTML Bootstrap 3 Modal triggered by a link, use the following markup&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;javascript:;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-toggle=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myModal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;More Info...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal fade&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModal&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;tabindex=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dialog&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-labelledby=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModalLabel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-hidden=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-dialog&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-content&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-header&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;close&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-dismiss=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-hidden=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;&amp;amp;times;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sr-only&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Close&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-title&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModalLabel&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php echo $name; ?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-body&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Some HTML content&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-footer&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn btn-default&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-dismiss=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Close&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn btn-primary&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Save changes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;wordpress&quot;&gt;WordPress&lt;/h2&gt;
&lt;p&gt;It’s pretty easy to wire up modals within WordPress.&lt;/p&gt;

&lt;p&gt;This function takes custom field data and uses it to build a modal:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*==============================================================================
  Biographical Repeater
  ============================================================================*/

function carawebs_biographical_repeater () {
  $repeater = &quot;people&quot;;

  if(get_field($repeater)){

    $i = 1;

    while(has_sub_field( $repeater )):

      $name = get_sub_field('name');
      $text = get_sub_field('biographical_info');
      $modal_text = get_sub_field('modal_text');
      $link = get_sub_field('linked_in');
      $image = get_sub_field('person_image');

      // In ACF, set image to return an image object
      // Image variables
      //$url = $image['url'];
      $title = $image['title'];
      $alt = $image['alt'];
      $caption = $image['caption'];

      // thumbnail
      $size = 'medium';
      $thumb = $image['sizes'][ $size ]; // Returns the URL of the correct size
      $width = $image['sizes'][ $size . '-width' ];
      $height = $image['sizes'][ $size . '-height' ];

      // The Output
      ?&amp;gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-sm-4 col-sm-offset-1&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;img-responsive&quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'title=&quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&quot;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$thumb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$alt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;post-excerpt&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Modal trigger - the target is built using a counter, $i --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;javascript:;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-toggle=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myModal-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;More Info about &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Modal Code Begins --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal fade&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModal-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;tabindex=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;role=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dialog&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-labelledby=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModalLabel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-hidden=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
             &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-dialog&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
              &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-content&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-header&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;close&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-dismiss=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;aria-hidden=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;&amp;amp;times;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sr-only&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Close&lt;span class=&quot;nt&quot;&gt;&amp;lt;/span&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-title&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myModalLabel&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-body&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$modal_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal-footer&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn btn-default&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-dismiss=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Close&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;btn btn-primary&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Save changes&lt;span class=&quot;nt&quot;&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                 &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
             &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Modal end --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$link&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;linked-in&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;'s Linked In Profile&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

    &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;endwhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;body-jump-in-chrome&quot;&gt;Body Jump in Chrome&lt;/h2&gt;
&lt;p&gt;I’m not sure if this occurs because of a fixed navbar, but the Bootstrap JS adds padding-right to the body element when the modal-open class is added:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;body class=&quot;page page-id-18 logged-in admin-bar about customize-support modal-open&quot; style=&quot;padding-right: 15px;&quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This can be corrected with:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;Prevent&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;Modal&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;Jumping&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-------------------------&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.modal-open&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;padding-right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;!important&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 25 Sep 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/09/bootstrap-modal/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/09/bootstrap-modal/</guid>
      </item>
      
    
      
      <item>
        <title>Remove Unused CSS in WordPress</title>
        <description>&lt;p&gt;#Using Grunt Uncss with WordPress/Roots
Building a site with the Bootstrap framework is a great way to take advantage of free open source styling.&lt;/p&gt;

&lt;p&gt;CSS frameworks like Foundation and Bootstrap can’t be ignored - they are efficient collaborative efforts - and they only look “samey” when developers/designers get lazy.&lt;/p&gt;

&lt;p&gt;When building a site with Bootstrap 3 under the Roots framework, you’ll typically have a minified CSS file of approximately 131kB. This is quite big, and the majority of styles won’t be used.&lt;/p&gt;

&lt;p&gt;One option is to comment out the LESS modules that aren’t being used so that they are not compiled (no carousel? don’t compile carousel.less) but this is a blunt tool and still results in many CSS rules being loaded in the browser.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;https://github.com/giakki/uncss&quot;&gt;UnCSS&lt;/a&gt;. This is a tool that removes unused CSS from stylesheets. it efficiently turns a sledgehammer into a precision instrument.&lt;/p&gt;

&lt;p&gt;UnCSS had been turned into a &lt;a href=&quot;https://github.com/addyosmani/grunt-uncss&quot;&gt;Grunt module&lt;/a&gt; by Addy Osmani.&lt;/p&gt;

&lt;p&gt;Though it has been designed to work with static sites, Liam Gladdy has developed a workaround for WordPress that works exceptionally well. There is a complete description of Liam’s method in &lt;a href=&quot;https://www.gladdy.uk/blog/2014/04/13/using-uncss-and-grunt-uncss-with-wordpress/&quot;&gt;this blog article&lt;/a&gt;. It involves using a &lt;a href=&quot;https://github.com/lgladdy/JSON-Sitemap-Generator-for-Grunt-UnCSS-with-WordPress&quot;&gt;WordPress plugin&lt;/a&gt; to build a JSON sitemap, and passing this to the UnCSS Grunt task. The UnCSS magic then checks each page of your dynamically generated site, and removes any unused style rules from the compiled CSS. This is an amazingly useful resource - and has the potential to give a significant performance boost.&lt;/p&gt;

&lt;p&gt;We modified the Roots &lt;code class=&quot;highlighter-rouge&quot;&gt;Gruntfile.js&lt;/code&gt; to manage all this - adding some minification for further savings.&lt;/p&gt;

&lt;h2 id=&quot;build-the-sitemap&quot;&gt;Build the Sitemap&lt;/h2&gt;
&lt;p&gt;Create a &lt;code class=&quot;highlighter-rouge&quot;&gt;mu-plugins&lt;/code&gt; directory in the wp-content directory of your development site, and add the &lt;a href=&quot;https://github.com/lgladdy/JSON-Sitemap-Generator-for-Grunt-UnCSS-with-WordPress&quot;&gt;JSON sitemap plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You’ll need to autoload the mu plugin - create a file called &lt;code class=&quot;highlighter-rouge&quot;&gt;load.php&lt;/code&gt; inside the mu-plugins dirtectory, and add the following line, referencing the correct path:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;require WPMU_PLUGIN_DIR.'/JSON-Sitemap-Generator/grunt-plugin.php';
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Make sure &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt; includes the following lines before running &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo npm install&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.4.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-clean&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.5.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-cssmin&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;^0.10.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-jshint&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.6.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-less&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.9.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-uglify&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.2.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-contrib-watch&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.5.3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-exec&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;^0.4.6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-uncss&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;^0.3.6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;grunt-wp-version&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~0.1.0&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Add an exec task to &lt;code class=&quot;highlighter-rouge&quot;&gt;Gruntfile.js&lt;/code&gt; that builds the sitemap:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nl&quot;&gt;get_grunt_sitemap&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;c1&quot;&gt;// the output of the show_sitemap() function (from the plugin) used to build sitemap.json&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'curl --silent --output sitemap.json http://localhost/useful/?show_sitemap'&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-an-uncss-grunt-task&quot;&gt;Create an UnCSS Grunt Task&lt;/h2&gt;
&lt;p&gt;UnCSS task, followed by a cssmin task to minify the output CSS file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;uncss&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nl&quot;&gt;dist&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;nl&quot;&gt;options&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;nl&quot;&gt;ignore&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;c1&quot;&gt;// needed for Bootstrap's transitions&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.slid.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.slide.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.fade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.fade.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapse.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapsing'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.alert-danger'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.logged-in .navbar-default'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev.right'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.right'&lt;/span&gt;

          &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;stylesheets&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'assets/css/main.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;ignoreSheets&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/fonts.googleapis/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;urls&lt;/span&gt;         &lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Overwritten in load_sitemap_and_uncss task&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'assets/css/main.css'&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'**/*.php'&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;cssmin&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;options&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;c1&quot;&gt;// cssmin has a problem with relative urls. Ref: http://stackoverflow.com/questions/23916622/how-to-rewrite-relative-url-in-minified-css-with-cssmin&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// set 'noAdvanced: true' to circumvent this&lt;/span&gt;
                &lt;span class=&quot;nl&quot;&gt;keepSpecialComments&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;c1&quot;&gt;//target: 'commonDir',&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;noAdvanced&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;banner&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/* ======= David Egan, carawebs: http://carawebs.com =======*/'&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

          &lt;span class=&quot;nl&quot;&gt;files&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;s2&quot;&gt;&quot;assets/css/main.min.css&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;assets/css/main.css&quot;&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;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;register-tasks&quot;&gt;Register Tasks&lt;/h2&gt;
&lt;p&gt;Register a task that loads sitemap.json. Add the UnCSS tasks to a “build” task:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'load_sitemap_json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sitemap_urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readJSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./sitemap.json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// pass the URLs to the uncss:dist task&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'uncss.dist.options.urls'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sitemap_urls&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;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'deploy_build'&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;s1&quot;&gt;'clean'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//'less',&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'less:deploy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'uglify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'exec:get_grunt_sitemap'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'load_sitemap_json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'uncss:dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'cssmin:css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'version'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;entire-gruntfile-roots-65&quot;&gt;Entire Gruntfile, Roots 6.5&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;s1&quot;&gt;'use strict'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;grunt&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;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;initConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;jshint&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;na&quot;&gt;options&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;na&quot;&gt;jshintrc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'.jshintrc'&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;all&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;s1&quot;&gt;'Gruntfile.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'assets/js/*.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'!assets/js/scripts.min.js'&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;na&quot;&gt;less&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;na&quot;&gt;dist&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;na&quot;&gt;files&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;s1&quot;&gt;'assets/css/main.min.css'&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;s1&quot;&gt;'assets/less/app.less'&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;na&quot;&gt;options&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;na&quot;&gt;compress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// LESS source map&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// To enable, set sourceMap to true and update sourceMapRootpath based on your install&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;sourceMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;sourceMapFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'assets/css/main.min.css.map'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;sourceMapRootpath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/useful/wp-content/themes/useful-studio/'&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// '/useful' necessary cos site not in root of domain&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;na&quot;&gt;deploy&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;na&quot;&gt;files&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;s1&quot;&gt;'assets/css/main.css'&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;s1&quot;&gt;'assets/less/app.less'&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;uglify&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;na&quot;&gt;dist&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;na&quot;&gt;files&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;s1&quot;&gt;'assets/js/scripts.min.js'&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;s1&quot;&gt;'assets/js/plugins/bootstrap/transition.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/alert.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/button.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/carousel.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/collapse.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/dropdown.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/modal.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/tooltip.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/popover.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/scrollspy.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/tab.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/bootstrap/affix.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//'assets/js/plugins/bootstrap-touch-carousel.js',// swipe support&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/plugins/*.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'assets/js/_*.js'&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;na&quot;&gt;options&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;c1&quot;&gt;// JS source map: to enable, uncomment the lines below and update sourceMappingURL based on your install&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// sourceMap: 'assets/js/scripts.min.js.map',&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// sourceMappingURL: '/app/themes/roots/assets/js/scripts.min.js.map'&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;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;version&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;na&quot;&gt;options&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;na&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'lib/scripts.php'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'assets/css/main.min.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;cssHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'roots_main'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'assets/js/scripts.min.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;jsHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'roots_scripts'&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;na&quot;&gt;watch&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;na&quot;&gt;less&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;na&quot;&gt;files&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;s1&quot;&gt;'assets/less/*.less'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'assets/less/bootstrap/*.less'&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;tasks&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;s1&quot;&gt;'less'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'version'&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;na&quot;&gt;js&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;na&quot;&gt;files&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;s1&quot;&gt;'&amp;lt;%= jshint.all %&amp;gt;'&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;tasks&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;s1&quot;&gt;'jshint'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'uglify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'version'&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;na&quot;&gt;livereload&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;c1&quot;&gt;// Browser live reloading&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// https://github.com/gruntjs/grunt-contrib-watch#live-reloading&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;options&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;na&quot;&gt;livereload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;files&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;s1&quot;&gt;'assets/css/main.min.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'assets/js/scripts.min.js'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'templates/*.php'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'*.php'&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;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;clean&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;na&quot;&gt;dist&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;s1&quot;&gt;'assets/css/main.min.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'assets/js/scripts.min.js'&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;na&quot;&gt;exec&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;na&quot;&gt;get_grunt_sitemap&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;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'curl --silent --output sitemap.json http://localhost/useful/?show_sitemap'&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;c1&quot;&gt;// Using uncss with WordPress:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// https://gladdy.uk/blog/2014/04/13/using-uncss-and-grunt-uncss-with-wordpress/&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;uncss&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;na&quot;&gt;dist&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;na&quot;&gt;options&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;na&quot;&gt;ignore&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;c1&quot;&gt;// needed for Bootstrap's transitions&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.slid.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.slide.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.fade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.fade.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapse'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapse.in'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.collapsing'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.alert-danger'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.logged-in .navbar-default'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .next.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .prev.right'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s1&quot;&gt;'.carousel-inner &amp;gt; .active.right'&lt;/span&gt;

          &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;stylesheets&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;s1&quot;&gt;'assets/css/main.css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;ignoreSheets&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;sr&quot;&gt;/fonts.googleapis/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;urls&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;c1&quot;&gt;//Overwritten in load_sitemap_and_uncss task&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;files&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;s1&quot;&gt;'assets/css/main.css'&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;s1&quot;&gt;'**/*.php'&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;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;cssmin&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;na&quot;&gt;options&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;c1&quot;&gt;// cssmin has a problem with relative urls. Ref: http://stackoverflow.com/questions/23916622/how-to-rewrite-relative-url-in-minified-css-with-cssmin&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// set 'noAdvanced: true' to circumvent this&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;keepSpecialComments&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;c1&quot;&gt;//target: 'commonDir',&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;noAdvanced&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;banner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/* ======= David Egan, carawebs: http://carawebs.com =======*/'&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;

          &lt;span class=&quot;na&quot;&gt;files&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;s2&quot;&gt;&quot;assets/css/main.min.css&quot;&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;s2&quot;&gt;&quot;assets/css/main.css&quot;&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;p&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;c1&quot;&gt;// Load tasks&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-clean'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-jshint'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-uglify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-watch'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-less'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-wp-version'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-exec'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-uncss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadNpmTasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'grunt-contrib-cssmin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Register tasks&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'default'&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;s1&quot;&gt;'clean'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'less'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'uglify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'version'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;


&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'load_sitemap_json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sitemap_urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readJSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./sitemap.json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'uncss.dist.options.urls'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sitemap_urls&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;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'deploy_build'&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;s1&quot;&gt;'clean'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//'less',&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'less:deploy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'uglify'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'exec:get_grunt_sitemap'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'load_sitemap_json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'uncss:dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'cssmin:css'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;s1&quot;&gt;'version'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'dev'&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;s1&quot;&gt;'watch'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Fri, 19 Sep 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/09/uncss-wordpress-grunt/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/09/uncss-wordpress-grunt/</guid>
      </item>
      
    
      
      <item>
        <title>Glyphicons CSS for Bootstrap 3</title>
        <description>&lt;p&gt;To add Glyphicons in CSS, use pseudo classes. For example, this code substitutes a glyphicon left chevron for the usual bullet in the .entry-content ul:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nc&quot;&gt;.entry-content&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;padding-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.entry-content&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;20px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&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;nc&quot;&gt;.entry-content&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;'Glyphicons Halflings'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;/* font-family: FontAwesome; */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;80%&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.entry-content&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;ul&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:before&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;'\e080'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;/* content: '\f105'; // Font awesome equivalent */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Go here:
&lt;a href=&quot;http://glyphicons.bootstrapcheatsheets.com/&quot;&gt;Glyphicons Cheatsheet for Bootstrap 3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;nuff said!&lt;/p&gt;
</description>
        <pubDate>Thu, 18 Sep 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/09/bootstrap-glyphicons-cheatsheet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/09/bootstrap-glyphicons-cheatsheet/</guid>
      </item>
      
    
      
      <item>
        <title>Customise WordPress Menu Widget</title>
        <description>&lt;p&gt;WordPress has a handy menu widget that allows you to select and display a navigation menu in a registered widget area (like a sidebar or footer).&lt;/p&gt;

&lt;p&gt;By copying the code from WP core, modifying it, and adding it to either a custom function or a plugin, the menu output can be customised.&lt;/p&gt;

&lt;p&gt;In this case, the li elements are prepended by stars (delivered by font awesome).&lt;/p&gt;

&lt;h2 id=&quot;php&quot;&gt;PHP&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*==============================================================================
  Modified Navigation Menu widget class
*=============================================================================*/

class Carawebs_Nav_Menu_Widget extends WP_Widget {

	function __construct() {
		$widget_ops = array( 'description' =&amp;gt; __('Add a custom menu to your sidebar.') );
		parent::__construct( 'nav_menu', __('Carawebs Custom Menu'), $widget_ops );
	}
	/*
  //constructor -- name this the same as the class above
    function Carawebs_Nav_Menu_Widget() {
        parent::WP_Widget(false, $name = 'Carawebs Custom Menu');
    }
  */

	function widget($args, $instance) {
		// Get menu
		$nav_menu = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;

		if ( !$nav_menu )
			return;

		// This filter is documented in wp-includes/default-widgets.php
		$instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this-&amp;gt;id_base );

		echo $args['before_widget'];

		if ( !empty($instance['title']) )
			echo $args['before_title'] . $instance['title'] . $args['after_title'];

    // Add &lt;span class=&quot;nt&quot;&gt;&amp;lt;i&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt; or classes for customisation
		wp_nav_menu( array( 'fallback_cb' =&amp;gt; '', 'menu' =&amp;gt; $nav_menu, 'menu_class'=&amp;gt; 'i-ul', 'before'=&amp;gt;'&lt;span class=&quot;nt&quot;&gt;&amp;lt;i&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon-star-sharp i-li orange&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;' ));

		echo $args['after_widget'];
	}

	function update( $new_instance, $old_instance ) {
		$instance['title'] = strip_tags( stripslashes($new_instance['title']) );
		$instance['nav_menu'] = (int) $new_instance['nav_menu'];
		return $instance;
	}

	function form( $instance ) {
		$title = isset( $instance['title'] ) ? $instance['title'] : '';
		$nav_menu = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';

		// Get menus
		$menus = wp_get_nav_menus( array( 'orderby' =&amp;gt; 'name' ) );

		// If no menus exists, direct the user to go and create some.
		if ( !$menus ) {
			echo '&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;'. sprintf( __('No menus have been created yet. &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Create some&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;.'), admin_url('nav-menus.php') ) .'&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;';
			return;
		}
		?&amp;gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;for=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Title:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;widefat&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;for=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'nav_menu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Select Menu:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;select&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'nav_menu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get_field_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'nav_menu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menus&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu&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;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;option value=&quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;term_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&quot;'&lt;/span&gt;
					&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$nav_menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;term_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
					&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$menu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/option&amp;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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&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;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'widgets_init'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;create_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'return register_widget(&quot;Carawebs_Nav_Menu_Widget&quot;);'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Unregister the default nav menu widget
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;remove_WP_Nav_widget&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;nx&quot;&gt;unregister_widget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'WP_Nav_Menu_Widget'&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;nx&quot;&gt;add_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'widgets_init'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'remove_WP_Nav_widget'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;css-to-style-the-menu&quot;&gt;CSS to Style the Menu&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nt&quot;&gt;i-ul&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inline-block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;padding-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2.142857142857143em&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;list-style-type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;none&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;nc&quot;&gt;.i-ul&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;li&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;relative&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;nc&quot;&gt;.i-li&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inline-block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-2.142857142857143em&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2.142857142857143em&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;text-align&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Tue, 02 Sep 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/09/modify-wp-menu-widget/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/09/modify-wp-menu-widget/</guid>
      </item>
      
    
      
      <item>
        <title>Row back to an Older Git Repo</title>
        <description>&lt;p&gt;Sometimes you might accidentally pull changes from a remote repo by running &lt;code class=&quot;highlighter-rouge&quot;&gt;git pull origin master&lt;/code&gt; inadvertently overwriting local changes.&lt;/p&gt;

&lt;p&gt;Fortunately there may be a way to go back to the pre-pulled state.&lt;/p&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;git reflog&lt;/code&gt;. This will provide an output like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;60a22c5 HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;0&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit: Side commenting system
66e1412 HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;1&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: pull origin master: Fast-forward
deff5af HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;2&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit: grunt build
477fd3d HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit: &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;setup
497e4b7 HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;4&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit: sidebar dropdown menu
1e18e81 HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;5&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit: Live reload enabled, sourcemaps working
8a1a95f HEAD@&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;6&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;: commit &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;initial&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: First Commit&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can revert to one of these commits. E.g.:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git reset --hard 60a22c5&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Git will output a message: &lt;code class=&quot;highlighter-rouge&quot;&gt;HEAD is now at 60a22c5 Side commenting system&lt;/code&gt; and you’ll be back at this commit.&lt;/p&gt;
</description>
        <pubDate>Wed, 27 Aug 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/08/row-back-git/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/08/row-back-git/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up Chrome DevTools Workspace</title>
        <description>&lt;p&gt;Setting up Workspaces allows Chrome DevTools to write to disc. This is handy during local development - it speeds up workflow by allowing changes to LESS/CSS in the Chrome DevTools “Sources” window.&lt;/p&gt;

&lt;p&gt;It requires compiled CSS (e.g. from LESS) to be source mapped - in our case this is usually taken care of by the Grunt &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-contrib-less&lt;/code&gt; module.&lt;/p&gt;

&lt;h2 id=&quot;set-up-workspaces&quot;&gt;Set up Workspaces&lt;/h2&gt;
&lt;p&gt;The sources tab is basically a file navigator in the Chrome Dev Tools sidebar that shows resources loaded by the web page. Set it up to write to disk:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open local webpage NOTE - the page must be server output for LESS source mapping to work&lt;/li&gt;
  &lt;li&gt;Set up LESS source maps&lt;/li&gt;
  &lt;li&gt;Open Dev Tools&lt;/li&gt;
  &lt;li&gt;Right click in the navigation area of the “Sources” tab&lt;/li&gt;
  &lt;li&gt;Select “Add Folder to Workspace”&lt;/li&gt;
  &lt;li&gt;Give DevTools access - the folder will appear in the IDE-like navigation&lt;/li&gt;
  &lt;li&gt;Right click on a file within the folder&lt;/li&gt;
  &lt;li&gt;Select “Map to File System”&lt;/li&gt;
  &lt;li&gt;DevTools wil recognise if the file on the filesystem has the same name as a page resource (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost:9000/less/main.less&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;user/testsite/css/main.less&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This only needs to be done once per project.&lt;/p&gt;

&lt;h2 id=&quot;using-the-devtools-workspace&quot;&gt;Using the DevTools Workspace&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Right click and inspect element&lt;/li&gt;
  &lt;li&gt;Select the LESS or CSS file associated with the rule that you want to edit&lt;/li&gt;
  &lt;li&gt;The relevant file opens in the Sources tab&lt;/li&gt;
  &lt;li&gt;Edit the file and click &lt;code class=&quot;highlighter-rouge&quot;&gt;ctrl + s&lt;/code&gt; to write changes to disk&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;set-up-less-sourcemap&quot;&gt;Set Up LESS Sourcemap&lt;/h2&gt;
&lt;p&gt;Sample Gruntfile.js less task for local WordPress installation - requires &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-contrib-less&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;less: {
      dist: {
        files: {
          'assets/css/main.min.css': [
            'assets/less/app.less'
          ]
        },
        options: {
          compress: true,
          // LESS source map
          // To enable, set sourceMap to true and update sourceMapRootpath based on your install
          sourceMap: true,
          sourceMapFilename: 'assets/css/main.min.css.map',
          sourceMapRootpath: '/useful/wp-content/themes/useful-studio/' // '/useful' necessary cos site not in root of domain
        }
      }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Sample less task from a static HTML site served by means of &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt-contrib-connect&lt;/code&gt; module, serving on port 9000:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;less: {
      development: {
        options: {
          compress: true,
          sourceMap: true,
          sourceMapRootpath: 'http://localhost:9000/', // adds a path onto the less files in the source map
          sourceMapFilename: 'css/agency.css.map'
        },
        files: {'less/main.min.css': [
            'less/main.less']
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The sourcemap is created, providing a reference to the relevant LESS files. The sourcemap is in turn referenced in the compiled CSS, in a comment at the end of the file.&lt;/p&gt;
</description>
        <pubDate>Sat, 16 Aug 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/08/chrome-workspaces/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/08/chrome-workspaces/</guid>
      </item>
      
    
      
      <item>
        <title>Install Jekyll on Ubuntu</title>
        <description>&lt;p&gt;Jekyll is a static site generator that is “blog aware” - it looks like a dynamic website (and really it is) even though it is served up by static HTML and does not have a database. All the automatic connection and site building takes place locally, before the site is uploaded to production. With some Grunt configuration using rsync, Jekyll sites are easily deployed. Jekyll is not a CMS.&lt;/p&gt;

&lt;p&gt;Jekyll requirements:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ruby-lang.org/en/installation/&quot;&gt;Ruby&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://rubygems.org/pages/download&quot;&gt;RubyGems&lt;/a&gt; - package management framework for Ruby&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://nodejs.org/&quot;&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://gorails.com/setup/ubuntu/14.04&quot;&gt;Useful article&lt;/a&gt; by Chris Oliver on setting up Ruby on Rails on Ubuntu 14.04 Trusty Tahr. This includes an interactive script generator that allows different versions of Ruby to be installed.&lt;/p&gt;

&lt;h2 id=&quot;set-up-ruby&quot;&gt;Set Up Ruby&lt;/h2&gt;

&lt;p&gt;Ruby dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install Ruby using rbenv - will result in a more up to date version of Ruby compared with “sudo apt-get install ruby”.&lt;/p&gt;

&lt;p&gt;First install rbenv. More info on rbenv &lt;a href=&quot;https://github.com/sstephenson/rbenv&quot;&gt;here&lt;/a&gt;. This code based on the &lt;a href=&quot;https://gorails.com/setup/ubuntu/14.04&quot;&gt;Chris Oliver article&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd
git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'export PATH=&quot;$HOME/.rbenv/bin:$PATH&quot;' &amp;gt;&amp;gt; ~/.bashrc
echo 'eval &quot;$(rbenv init -)&quot;' &amp;gt;&amp;gt; ~/.bashrc
exec $SHELL
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Install ruby-build:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH=&quot;$HOME/.rbenv/plugins/ruby-build/bin:$PATH&quot;' &amp;gt;&amp;gt; ~/.bashrc
exec $SHELL

rbenv install 2.1.2
rbenv global 2.1.2
ruby -v
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Install Ruby gems:
&lt;code class=&quot;highlighter-rouge&quot;&gt;gem update --system          # may need to be sudo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tell Rubygems not to install local docs:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;echo &quot;gem: --no-ri --no-rdoc&quot; &amp;gt; ~/.gemrc&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;nodejs&quot;&gt;NodeJS&lt;/h2&gt;
&lt;p&gt;Add this using a PPA repositiory.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo add-apt-repository ppa:chris-lea/node.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install nodejs&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-jekyll&quot;&gt;Install Jekyll&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo gem install jekyll&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;build-a-jekyll-site&quot;&gt;Build a Jekyll site&lt;/h2&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gem install jekyll
jekyll new mysite
cd mysite
jekyll serve
# =&amp;gt; Now browse to http://localhost:4000
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 03 Aug 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/08/setup-jekyll-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/08/setup-jekyll-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Install Atom Ubuntu</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://atom.io/&quot;&gt;Atom&lt;/a&gt; is an excellent open source text-editor by GitHub, released under the MIT license. To install on Ubuntu, add the webupd8team ppa:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo add-apt-repository ppa:webupd8team/atom&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install atom&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the Emmet package through the Atom package manager.&lt;/p&gt;
</description>
        <pubDate>Sun, 03 Aug 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/08/setup-atom-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/08/setup-atom-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Set up a LAMP stack</title>
        <description>&lt;h2 id=&quot;install-apache&quot;&gt;Install Apache&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install apache2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If Apache has installed correctly, &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost&lt;/code&gt; will now display the Apache2 Ubuntu Default Page.&lt;/p&gt;

&lt;h2 id=&quot;install-mysql&quot;&gt;Install MySQL&lt;/h2&gt;

&lt;p&gt;We will also include “helper” packages:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install mysql-server php5-mysql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It is not necessary to run &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get update&lt;/code&gt; before installing MySQL because it was run prior to installing Apache - so we can assume that everything is up to date.&lt;/p&gt;

&lt;p&gt;Set passwords for root user when prompted (twice).&lt;/p&gt;

&lt;p&gt;Set up MySQL database directory structure:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo mysql_install_db&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Remove dangerous defaults - removes anonymous users, and prevents root login remotely, etc. Be careful with removal of remote root login - new user will be necessary. This script is probably not necessary on local environment install:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo mysql_secure_installation&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the MySQL install goes wrong and you need to start again:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get remove --purge mysql*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get autoremove&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get autoclean&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-php&quot;&gt;Install PHP&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Modify default for Apache serving files, give preference to PHP:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/apache2/mods-enabled/dir.conf&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;IfModule mod_dir.c&amp;gt;
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Bring index.php to head of the queue.&lt;/p&gt;

&lt;p&gt;Restart Apache:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;php-modules&quot;&gt;PHP Modules&lt;/h2&gt;

&lt;p&gt;Get a list: &lt;code class=&quot;highlighter-rouge&quot;&gt;apt-cache search php5-&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;test-php&quot;&gt;Test PHP:&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /var/www/html/info.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Enter:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
phpinfo();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Don’t leave the file in place - security vulnerability:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo rm /var/www/html/info.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE: Document root is currently /var/www/html&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;change-document-root--enable-rewrites&quot;&gt;Change Document Root &amp;amp; Enable Rewrites&lt;/h2&gt;

&lt;p&gt;To change document root to /var/www, and enable rewrites.&lt;/p&gt;

&lt;p&gt;Make sure mod_rewrite is installed:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo a2enmod rewrite&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If mod_rewrite is not enabled, running this command will enable it. Restart Apache:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;service apache2 restart&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Find output of &lt;code class=&quot;highlighter-rouge&quot;&gt;ls /etc/apache2/sites-enabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;000-default.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This file is used for httpd configuration in /etc/apache2/sites-available/&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;Edit the config file:
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/apache2/sites-available/000-default.conf&lt;/code&gt;
…by adding this code block, and commenting out the &lt;code class=&quot;highlighter-rouge&quot;&gt;DocumentRoot /var/www/html&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DocumentRoot /var/www
&amp;lt;Directory /var/www/&amp;gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;hr /&gt;
&lt;p&gt;Restart Apache:
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-phpmyadmin&quot;&gt;Install PHPMyAdmin&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install phpmyadmin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /etc/apache2/apache2.conf&lt;/code&gt;
…and include this line:&lt;/p&gt;

&lt;p&gt;Include /etc/phpmyadmin/apache.conf&lt;/p&gt;

&lt;p&gt;“Since Ubuntu 13.10 (Saucy Salamander), Apache no longer loads configuration files from the /etc/apache2/conf.d directory. Instead, they are loaded from the /etc/apache2/conf-enabled directory. Therefore, if you need to manually include the phpMyAdmin-shipped Apache configuration file, you must run the following:”&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-enabled/phpmyadmin.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo /etc/init.d/apache2 reload&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-php-curl&quot;&gt;Install PHP curl&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install php5-curl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo service apache2 restart&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-curl&quot;&gt;Install cURL&lt;/h2&gt;
&lt;p&gt;“Curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberosâ€¦), file transfer resume, and proxy tunneling.”&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install curl libcurl3 libcurl3-dev php5-curl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This allows WP-CLI to be installed.&lt;/p&gt;
</description>
        <pubDate>Fri, 01 Aug 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/08/setup-lamp-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/08/setup-lamp-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Bootstrap Carousel &amp; Thumbnail Navigation for WordPress</title>
        <description>&lt;p&gt;A Bootstrap carousel with thumbnail controls for WordPress.&lt;/p&gt;

&lt;p&gt;Project files are &lt;a href=&quot;https://github.com/DavidCWebs/bootstrap-carousel-thumbnail-nav&quot;&gt;available on GitHub&lt;/a&gt; - fork or clone your own version.&lt;/p&gt;

&lt;h2 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Paste contents of carousel-linked-thumbnails.php into the theme custom.php file&lt;/li&gt;
  &lt;li&gt;Create ACF repeater field called &lt;strong&gt;carousel_images&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Create a sub field &lt;strong&gt;image&lt;/strong&gt; - set this to return image ID&lt;/li&gt;
  &lt;li&gt;If using the Roots framework, add &lt;strong&gt;js/_carousel.js&lt;/strong&gt; to the theme assets/js/vendor directory&lt;/li&gt;
  &lt;li&gt;If you use a different directory for the js files, remember to reference it properly in enqueue.php&lt;/li&gt;
  &lt;li&gt;Include &lt;strong&gt;jquery.touchSwipe.min.js&lt;/strong&gt; and &lt;strong&gt;touchControl.js&lt;/strong&gt; in assets/js/vendor for mobile swipe support.&lt;/li&gt;
  &lt;li&gt;Enqueue the javascript files by adding the contents of &lt;strong&gt;enqueue.php&lt;/strong&gt; to your theme custom.php file, or /lib/scripts.php for the Roots framework&lt;/li&gt;
  &lt;li&gt;Include the contents of carousel-linked-thumbnails.css in the theme CSS/LESS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;intro-id&quot;&gt;Intro ID&lt;/h2&gt;
&lt;p&gt;This is really two linked carousels:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A full size carousel, populated from an ACF repeater field&lt;/li&gt;
  &lt;li&gt;A thumbnail sized carousel, populated from the same field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The thumbnail carousel targets the main carousel by means of the Bootstrap &lt;strong&gt;data-target&lt;/strong&gt; attribute. The following code block shows how the carousel with id “myCarousel” is targeted. $count works as a counter, and because both sliders are populated from the same repeater field cross-referencing is easy.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;?&amp;gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-selector-&amp;lt;?php echo $count; ?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data-slide-to=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;?php echo $count; ?&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;?php echo $thumbimage[0]; ?&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;?php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The data attribute &lt;strong&gt;data-slide-to&lt;/strong&gt; is used to pass a raw slide index to myCarousel - it does what it says on the tin. In this case, clicking the thumbnail triggers a slide to the $count slide on the main carousel.&lt;/p&gt;

&lt;h2 id=&quot;building-the-carousels&quot;&gt;Building the Carousels&lt;/h2&gt;
&lt;p&gt;The carousel is dynamic - it takes advantage of the Advanced Custom Fields WordPress plugin that allows the user to upload/select images.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An ACF field group is built, and associated with a Custom Post Type (in this case, the CPT “project”).&lt;/li&gt;
  &lt;li&gt;A repeater field is added - the repeater field is a premium add-on for ACF (it is extremely useful and ridiculously under-priced).&lt;/li&gt;
  &lt;li&gt;An “image” sub-field is added to the repeater field.&lt;/li&gt;
  &lt;li&gt;If necessary, extra fields can be added to allow fine user control over what is displayed on each slide.&lt;/li&gt;
  &lt;li&gt;The image data for each slide is held as a row in the ACF repeater field.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these files, the repeater field is named &lt;strong&gt;carousel_images&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The image sub-field is named &lt;strong&gt;image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The PHP function for building the carousels is in the file &lt;strong&gt;carousel-linked-thumbnails.php&lt;/strong&gt;. The code in this file could be added to the theme &lt;strong&gt;custom.php&lt;/strong&gt; file. View the code here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*==============================================================================
  Carousel from ACF Repeater Field.
==============================================================================*/
/*  This uses repeater field data, where the sub-field is the &quot;image&quot; type.
*   Set ACF to return image ID for the sub-field.
*   Repeater field name  = 'carousel_images'
*   Sub field 1          = 'image'
*/

function carawebs_carousel_images_slider() {

 $number = 0;
 $carousel_images = get_field('carousel_images');

  if(!empty($carousel_images) ){ // run if the repeater field has content
    ?&amp;gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- data-ride=&quot;carousel&quot; causes auto play class=&quot;slide&quot; causes slide--&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myCarousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel slide&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-ride=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Carousel items --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-inner&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$slidecount&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;//Allows unique ids on items
&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;has_sub_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'carousel_images'&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;nv&quot;&gt;$attachment_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_sub_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'image'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  		        &lt;span class=&quot;nv&quot;&gt;$size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;full&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// (thumbnail, medium, large, full or custom size)
&lt;/span&gt;  		        &lt;span class=&quot;nv&quot;&gt;$image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_get_attachment_image_src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$attachment_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  		        &lt;span class=&quot;c1&quot;&gt;// url = $image[0];
&lt;/span&gt;  		        &lt;span class=&quot;c1&quot;&gt;// width = $image[1];
&lt;/span&gt;  		        &lt;span class=&quot;c1&quot;&gt;// height = $image[2];
&lt;/span&gt;
              &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;slide-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$slidecount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$image&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

              &lt;span class=&quot;nv&quot;&gt;$slidecount&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;// End the while loop
&lt;/span&gt;
          &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Carousel nav --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;left carousel-control&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;prev&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;glyphicon glyphicon-chevron-left&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;right carousel-control&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;next&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;glyphicon glyphicon-chevron-right&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&amp;lt;!--============================================================================
  The Thumbnail Navigation
=============================================================================--&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel slide&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;thumb-carousel&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-inner&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

            &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt; &lt;span class=&quot;o&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;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;//added before the while loop to ensure the div gets opened
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;div id=&quot;item-'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&quot; class=&quot;item&quot;&amp;gt;&amp;lt;ul class=&quot;carousel-thumbnails&quot;&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;nv&quot;&gt;$rowcount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'carousel_images'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// the total number of images - counts rows in the ACF repeater array
&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;has_sub_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'carousel_images'&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;nv&quot;&gt;$count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                     &lt;span class=&quot;cm&quot;&gt;/*===========================================================*/&lt;/span&gt;
                     &lt;span class=&quot;nv&quot;&gt;$slidenumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// SET NUMBER OF SLIDES HERE
&lt;/span&gt;                     &lt;span class=&quot;cm&quot;&gt;/*===========================================================*/&lt;/span&gt;
                     &lt;span class=&quot;nv&quot;&gt;$thumb_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;get_sub_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'image'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                     &lt;span class=&quot;nv&quot;&gt;$thumbsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;thumbnail&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// (thumbnail, medium, large, full or custom size)
&lt;/span&gt;                     &lt;span class=&quot;nv&quot;&gt;$thumbimage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;wp_get_attachment_image_src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$thumb_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$thumbsize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                     &lt;span class=&quot;c1&quot;&gt;// url = $thumbimage[0];
&lt;/span&gt;                     &lt;span class=&quot;c1&quot;&gt;// width = $thumbimage[1];
&lt;/span&gt;                     &lt;span class=&quot;c1&quot;&gt;// height = $thumbimage[2];
&lt;/span&gt;
                     &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-target=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-selector-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data-slide-to=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                         &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$thumbimage&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;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

                 &lt;span class=&quot;c1&quot;&gt;// if multiple of 3 close div and open a new div
&lt;/span&gt;                 &lt;span class=&quot;nv&quot;&gt;$itemNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$slidenumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&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;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$slidenumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$rowcount&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;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div id=&quot;item-'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$itemNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&quot; class=&quot;item&quot;&amp;gt;&amp;lt;ul class=&quot;carousel-thumbnails&quot;&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;}&lt;/span&gt;

                &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;o&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;c1&quot;&gt;//make sure open div is closed
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- /.carousel-inner --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Carousel nav --&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;left carousel-control&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#thumb-carousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;prev&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;glyphicon glyphicon-chevron-left&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;right carousel-control&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#thumb-carousel&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-slide=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;next&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;glyphicon glyphicon-chevron-right&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;carousel-index&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- data passed here by jQuery for debugging purposes --&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- /.container for the #thumb-carousel --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- /.row this contains both carousels --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The initial if statement
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&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;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;function&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When using the Roots framework, add the code to &lt;strong&gt;lib/custom.php&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The function can then be used in page templates. In this example, the function is added to the &lt;strong&gt;content-single-project.php&lt;/strong&gt; template part:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;row&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;col-md-12&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;cp&quot;&gt;&amp;lt;?php carawebs_carousel_images_slider(); ?&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;controls&quot;&gt;Controls&lt;/h2&gt;

&lt;p&gt;Controls are built into &lt;strong&gt;/js/_carousel.js&lt;/strong&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Set up - give first items emphasis classes.
    Necessary because the slider is built dynamically
==============================================================================*/&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.carousel-inner .item:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Give active class to the first thumbnail image&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#thumb-carousel li:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;selected&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Give active class to the first thumbnail item (image-block)&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#thumb-carousel .item:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Prevent auto play, both carousels&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#myCarousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carousel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#thumb-carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carousel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;


&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Listen to the 'slid carousel' event to trigger code after each slide change
==============================================================================*/&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#myCarousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'slid.bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;c1&quot;&gt;// Useful variables&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bs.carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentIndex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getActiveIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carouselData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// To display a slide counter for debugging, enable this block.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Create a HTML element &amp;lt;div id=&quot;carousel-count&quot;&amp;gt;&amp;lt;/div&amp;gt; to display the text.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//var text = (currentIndex + 1) + &quot; of &quot; + total;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//$('#carousel-count').text(text);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Highlight the thumbnail corresponding to the currently displayed slide in the main carousel&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'[id^=carousel-selector-]'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;removeClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'selected'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'[id^=carousel-selector-'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;']'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'selected'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Display the thumbnail slider item that contains the current myCarousel slide
    Enable this code block for a simple shift (no slide)
==============================================================================*/&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Remove active class from #item-x&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//$('[id^=item-]').removeClass('active');&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Which item contains the current thumbnail&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//$( &quot;[id^=item-]&quot; ).has(&quot;[id^=carousel-selector-&quot;+(currentIndex)+&quot;]&quot;).addClass( &quot;active&quot; );&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    SLIDE to the thumbnail slider item that contains the current myCarousel slide
    Enable this code block for a sliding shift
==============================================================================*/&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Find the item in the thumb carousel that contains the currently displayed main image&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;targetItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[id^=item-]&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;has&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;[id^=carousel-selector-&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Find the index number of this item by getting the last character of the id string&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id_selector&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;targetItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id_selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id_selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Parse the string, return as an integer in base 10 format&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Make a correction, because the first thumbnail carousel item has a count of zero&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&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;c1&quot;&gt;// Create a HTML element &amp;lt;div id=&quot;carousel-index&quot;&amp;gt;&amp;lt;/div&amp;gt; to display the item index for debugging&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#carousel-index'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Force #thumb-carousel to slide to the correct item&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'#thumb-carousel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carousel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*==============================================================================
    Hiding Prev &amp;amp; Next Links at extremes
==============================================================================*/&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;checkitem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#myCarousel .carousel-inner .item:first&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&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;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.left&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.right&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;show&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#myCarousel .carousel-inner .item:last&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&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;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.right&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.left&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;show&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;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;.carousel-control&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;show&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;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;checkitem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#myCarousel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;slid.bs.carousel&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;checkitem&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;c1&quot;&gt;// Close the &quot;slid&quot; function&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;wordpress-enqueue-scripts&quot;&gt;WordPress: Enqueue Scripts&lt;/h2&gt;
&lt;p&gt;When working within WordPress it’s important to enqueue scripts properly - this prevents inefficient double loading of libraries and ensures that scripts load rationally.&lt;/p&gt;

&lt;p&gt;Within the Roots framework, the js files could be added to the assets/js folder and named with a leading underscore - they would then be concatenated into &lt;strong&gt;scripts.min.js&lt;/strong&gt;. This isn’t a bad option - but it means that unecessary kilobytes will be added to pages that don’t contain the carousel.&lt;/p&gt;

&lt;p&gt;Consider enqueueing the scripts only on the pages where they are required - in this case, the scripts are enqueued only on project CPT pages.&lt;/p&gt;

&lt;p&gt;For better efficiency, the raw js files could be targeted by Grunt and uglified.&lt;/p&gt;

&lt;p&gt;The enqueue script within the Roots framework are placed in &lt;strong&gt;lib/scripts.php&lt;/strong&gt; in order to keep all script calls rational. In other setups the enqueue function could be added to the &lt;strong&gt;custom.php&lt;/strong&gt; file.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function carawebs_carousel_control(){

	if ( is_singular( 'projects') ) { // only do this for &quot;project&quot; CPTs

    // Register the control script
    wp_register_script( 'carawebs_carousel', get_template_directory_uri() . '/assets/js/vendor/_carousel.js', array( 'jquery' ), null, true);
    wp_register_script('touchswipe', get_template_directory_uri() . '/assets/js/vendor/jquery.touchSwipe.min.js', array( 'jquery' ), null, true);
    wp_register_script('touchControl', get_template_directory_uri() . '/assets/js/vendor/touchControl.js', array( 'jquery' ), null, true);

	// Enqueue the carousel controls - they will be built into the footer
    wp_enqueue_script('carawebs_carousel');
    wp_enqueue_script('touchswipe');
    wp_enqueue_script('touchControl');
	}
}
// Add hooks for front-end
add_action('wp_enqueue_scripts', 'carawebs_carousel_control', 101);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;mobile-swipe-support&quot;&gt;Mobile Swipe Support&lt;/h2&gt;
&lt;p&gt;I used the &lt;a href=&quot;https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/blob/master/jquery.touchSwipe.js&quot;&gt;touchSwipe jQuery plugin&lt;/a&gt; to achieve swipe support for mobile devices. This plugin is copyright (c) 2010 Matt Bryson and is dual licensed under the MIT or GPL Version 2 licenses.&lt;/p&gt;

&lt;p&gt;I plan to build in conditional logic so that touchSwipe is only loaded for mobile devices.&lt;/p&gt;

&lt;h2 id=&quot;useful-tutorials&quot;&gt;Useful Tutorials&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.sitepoint.com/creating-javascript-sliders-using-twitter-bootstrap-3/&quot;&gt;http://www.sitepoint.com/creating-javascript-sliders-using-twitter-bootstrap-3/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 05 Jul 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/07/bootstrap-carousel-wordpress/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/07/bootstrap-carousel-wordpress/</guid>
      </item>
      
    
      
      <item>
        <title>Manipulating date format MySQL</title>
        <description>&lt;p&gt;Importing an “alien” date column into a WordPress format - necessary because the old date column contained data in the “VARCHAR” format. WordPress requires date to be in the “DATE” format.&lt;/p&gt;

&lt;p&gt;Delete unnecessary columns.&lt;/p&gt;

&lt;p&gt;Rename columns to suit WordPress schema.&lt;/p&gt;

&lt;p&gt;Rename the old date column to “OLDDATE”.&lt;/p&gt;

&lt;p&gt;Create a new column with the data-type “DATE”, named “post_date”:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open phpMyAdmin&lt;/li&gt;
  &lt;li&gt;Select “Structure”&lt;/li&gt;
  &lt;li&gt;Add a new Column&lt;/li&gt;
  &lt;li&gt;Name appropriately (e.g. WP date = “post_date”)&lt;/li&gt;
  &lt;li&gt;Select Type “DATE”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following SQL command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;UPDATE tablename SET post_date = str_to_date( OLDDATE, '%d/%m/%Y')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Where old dates are in string data-format, dd/mm/yyyy.&lt;/p&gt;

&lt;hr /&gt;
&lt;h2 id=&quot;copy-columns&quot;&gt;Manipulate Column Data&lt;/h2&gt;

&lt;p&gt;Copy data from ColumnA Data to ColumnB:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;UPDATE tablename SET columnB = columnA&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Delete table data:
&lt;code class=&quot;highlighter-rouge&quot;&gt;TRUNCATE tablename&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;
&lt;h2 id=&quot;table import&quot;&gt;Import Table Data, phpMyAdmin&lt;/h2&gt;

&lt;p&gt;Organise data on a test table, then &lt;strong&gt;rename before exporting&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select table&lt;/li&gt;
  &lt;li&gt;Select operations&lt;/li&gt;
  &lt;li&gt;Select “rename table to”&lt;/li&gt;
  &lt;li&gt;Give the table the same name as the target table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click “Export” in top level menu.&lt;/p&gt;

&lt;p&gt;Open the target DB, select the target table. Click import and select the recently exported DB.&lt;/p&gt;
</description>
        <pubDate>Tue, 01 Jul 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/07/mysql-date-modification/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/07/mysql-date-modification/</guid>
      </item>
      
    
      
      <item>
        <title>Responsive Images: Jekyll</title>
        <description>&lt;p&gt;How to add a responsive image to a Jekyll post:&lt;/p&gt;

&lt;p&gt;Create a folder called assets in the root directory of your project, into which any images, downloads or any other assets are placed. They can then be linked to in the post.&lt;/p&gt;

&lt;p&gt;Install jekyll-image-tag. This requires both Minimagick and Imagemagick to work.&lt;/p&gt;

&lt;p&gt;You can install Minimagick with the command:
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo gem install jekyll-minimagick&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In a plugin file within your projects _plugins directory add:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;# _plugins/my-plugin.rb
require &quot;jekyll-minimagick&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Define presets in your _config.yml file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;		image:
 		source: assets
 		 output: generated
  		presets:
   	 		users:
      		attr:
        	class: img-responsive
        	itemprop: image
      	width: 350
    	half:
    width: 500
    height: 500&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once you have the requirements installed, download jekyll-image-tag and copy image_tag.rb to your Jekyll _plugins folder.&lt;/p&gt;

&lt;p&gt;Link the image from your assets folder to your post using the format:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{% image preset or WxH path/to/img.jpg attr=&quot;value&quot; %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;My code looked like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;{% image 300x300 Caribbean_reef_shark.jpg class=&quot;img-responsive&quot; %}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 26 Jun 2014 12:54:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/06/responsive-images-jekyll/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/responsive-images-jekyll/</guid>
      </item>
      
    
      
      <item>
        <title>Syncing with Bitbucket</title>
        <description>&lt;h2 id=&quot;intro&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://bitbucket.org/&quot;&gt;Bitbucket&lt;/a&gt; is a great resource - it provides free multi-user version control for groups of up to five developers.&lt;/p&gt;

&lt;p&gt;It can also be a useful way of deploying to a development (or production) server.&lt;/p&gt;

&lt;p&gt;The work flow is as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Connect a local project directory with a remote Bitbucket repo&lt;/li&gt;
  &lt;li&gt;Clone the repo to a project directory on a remote server&lt;/li&gt;
  &lt;li&gt;Push changes from the local working directory to the Bitbucket remote repo&lt;/li&gt;
  &lt;li&gt;Pull changes from the remote Bitbucket repo to the remote development server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This allows all changes to be properly managed (for example, by means of git), and allows different developers to work on different branches. It has great tools for reviewing and merging changes.&lt;/p&gt;

&lt;p&gt;It’s a great set-up for small teams, and is free.&lt;/p&gt;

&lt;hr /&gt;
&lt;h2 id=&quot;push&quot;&gt;Easy Pushing&lt;/h2&gt;
&lt;p&gt;This can be partially automated. Firstly, set up SSH keys to allow communication between:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Your local machine and Bitbucket&lt;/li&gt;
  &lt;li&gt;The remote server and Bitbucket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are really good instructions for setting up SSH keys &lt;a href=&quot;https://confluence.atlassian.com/pages/viewpage.action?pageId=270827678&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, we’ll create an alias - “dir-push” that will manage the push to the repo.&lt;/p&gt;

&lt;p&gt;We’ll put this alias in ~/.bashrc so that it is globally accessible.&lt;/p&gt;

&lt;p&gt;Open ~/.bashrc and add the following lines:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#Push theme to Bitbucket&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;dir-push&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/path/to/development/dir; add -A; git commit; git push origin master&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Close the terminal and reopen.&lt;/p&gt;

&lt;p&gt;Now when you type “dir-push” on the command line, you’ll be prompted for a git commit message.&lt;/p&gt;

&lt;p&gt;This is quite a painless way to manage the push to the repo - you just need to type a single command and your commit message.&lt;/p&gt;

&lt;p&gt;I advise including a passphrase when you set up SSH keys - in case someone maliciously accesses your development machine - in which case you’ll also be prompted for the passphrase during the push.&lt;/p&gt;

&lt;h2 id=&quot;pull&quot;&gt;Easy Pulling&lt;/h2&gt;

&lt;p&gt;The idea here is to connect to a remote server by means of SSH, and pull the latest version of the Bitbucket repo to the relevant directory on the development server. This is a bit more complicated.&lt;/p&gt;

&lt;p&gt;It can be achieved easily with a GitHub repo, since you aren’t prompted for authentication when pulling. I’ve achieved this like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Pull the repo from GitHub to the development server&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The &amp;lt;&amp;lt;EOF part tells the shell that you're going to enter multi-lines until the ending EOF tag&lt;/span&gt;
ssh username@1.12.123.123 &lt;span class=&quot;sh&quot;&gt;&amp;lt;&amp;lt;EOF
cd /var/www/path/to/development/directory
git pull
logout
EOF
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;You should be logged out of the VPS&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;This won’t work with Bitbucket - the required verification causes the script to stall.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solution:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a shell script and add this to /usr/local/bin &lt;strong&gt;on the remote server&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Create a shell script &lt;strong&gt;on the local machine&lt;/strong&gt; (again, in /usr/local/bin) which starts an interactive SSH session and calls the remote script.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;local&quot;&gt;The Local Script&lt;/h2&gt;

&lt;p&gt;Create a suitably named file in the &lt;strong&gt;local&lt;/strong&gt; /usr/local/bin:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /usr/local/bin/pull-project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Pull the Bitbucket repo to the development server&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Open an SSH session and run the shell script &quot;remote-project-pull&quot;&lt;/span&gt;
ssh username@1.12.123.123 -t &lt;span class=&quot;s2&quot;&gt;&quot;remote-project-pull&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;alltogether&quot;&gt;The Remote Script&lt;/h2&gt;

&lt;p&gt;Create a suitably named file in the &lt;strong&gt;remote&lt;/strong&gt; /usr/local/bin:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano /usr/local/bin/remote-project-pull&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/path/to/development/directory
git pull
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;End Script - logging out of VPS&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;exit
echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Logged out of VPS&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now, when you’re working on your local development machine, you just enter the command “pull-project”. A SSH session will be opened, and the repo will be pulled from Bitbucket.&lt;/p&gt;

&lt;p&gt;Again, if you have set up a passphrase for the SSH connection between the remote server and Bitbucket (recommended), you’ll be prompted for the passphrase.&lt;/p&gt;

&lt;h2 id=&quot;other-options&quot;&gt;Other Options&lt;/h2&gt;
&lt;p&gt;There are other options that automate the deployment from Bitbucket to the development server. &lt;a href=&quot;http://brandonsummers.name/blog/2012/02/10/using-bitbucket-for-automated-deployments/&quot;&gt;This method&lt;/a&gt; looks interesting.&lt;/p&gt;

&lt;p&gt;I can see how that would be pretty useful in some circumstances - but I think this method is simple, leaves you with lots of control, and it’s just a couple of extra commands in your workflow. You can commit to the Bitbucket repo without clients necessarily seeing your work-in-progress.&lt;/p&gt;
</description>
        <pubDate>Wed, 25 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/syncing-to-development-bitbucket/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/syncing-to-development-bitbucket/</guid>
      </item>
      
    
      
      <item>
        <title>Custom Google Maps in Roots</title>
        <description>&lt;h2 id=&quot;intro&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The Google maps &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript/reference&quot;&gt;JavaScript API v3&lt;/a&gt; offers lots of opportunities to customise Google maps. The map can be styled to match the client website’s branding, retaining all the functionality of Google maps.&lt;/p&gt;

&lt;p&gt;To display a custom Google map:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Define (style) a div to be used as a map canvas&lt;/li&gt;
  &lt;li&gt;Initialise Google Maps&lt;/li&gt;
  &lt;li&gt;Define the map – when working in WordPress consider saving the map as a *.js file and enqueueing this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s important that these three elements are added to the document head in the specified order.&lt;/p&gt;

&lt;p&gt;The Google Styled Maps Wizard is a useful way of coding custom JSON data to be passed to your map, which is how the map gets it’s custom style. It’s not a particularly great way of creating an entire map but it’s useful for getting the right JSON data for particular element.&lt;/p&gt;

&lt;h2 id=&quot;locations&quot;&gt;Map Script &amp;amp; File Locations&lt;/h2&gt;
&lt;p&gt;Save the custom map script:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;theme/assets/js/vendor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Placing the map in this location means that it won’t be uglified by Grunt. This keeps the file out of the concatenation group, and allows us to control exactly when and where it is enqueued.&lt;/p&gt;

&lt;p&gt;The Grunt task in Roots concatenates all js files into a single file: /assets/js/scripts.min.js. For the most part this works well, as it reduces HTTP requests and thereby gives a performance boost.&lt;/p&gt;

&lt;p&gt;Sometimes we want to keep scripts out of the main js file - in this case, we only want to call the Google maps API and run our custom script on a single page. Therefore, the map script should be placed in the /assets/js/vendor directory.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;enqueue&quot;&gt;Enqueuing Scripts in Roots&lt;/h2&gt;

&lt;p&gt;Within the Roots structure, enqueuing of scripts is controlled in the &lt;code class=&quot;highlighter-rouge&quot;&gt;theme/lib/scripts.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Scripts can be enqueued conditionally (for example only on certain pages, as in the example below). The order in which scripts are deployed can also be controlled.&lt;/p&gt;

&lt;p&gt;In this file, define the map canvas:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function carawebs_map_style() {

	// Run on page 69 only
	if (is_page('69')) {
		echo '&lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;#map_canvas&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;548px&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;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;';
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Initialise the Google maps API on a specific page:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function carawebs_initialise_googlemaps(){

	if (is_page('69')) {
	    $googlescript = '&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://maps.googleapis.com/maps/api/js?sensor=false&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;';
	    echo $googlescript;
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Set up the map control script:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;function carawebs_googlemaps_control(){

	if (is_page('69')) {

    // Register the control script - note script location
    wp_register_script( 'carawebs_googlemap', get_template_directory_uri() . '/assets/js/vendor/google-map.js');

		// Pass variables to the script - this avoids having to hardcode the map marker in javascript
		// This could be a user-selected field
		$imagelocation = get_template_directory_uri() . . '/assets/img/marker.png';
		$site_variables = array(
			'markerImage' =&amp;gt; $imagelocation
			);

		wp_localize_script( 'carawebs_googlemap', 'carawebsMapVars', $site_variables );
		// This function makes variables available to carawebs_googlemap
		// Define the image in js like this: var image = (carawebsMapVars.markerImage);

	// Enqueue the map controls
    wp_enqueue_script('carawebs_googlemap');

	}
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Insert scripts &amp;amp; style definitions in the correct order in wp_head:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;// Add hooks for front-end
add_action('wp_head', 'carawebs_map_style', 1);
add_action('wp_head', 'carawebs_initialise_googlemaps', 2);
add_action('wp_enqueue_scripts', 'carawebs_googlemaps_control', 105);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;alltogether&quot;&gt;The Entire Enqueue Script&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;/*================================================
* The Google Map Script
* ==============================================*/

/* Add Google Map Script to Specific Page */

function carawebs_map_style() {

	// Run on page 69 only
	if (is_page('69')) {
		echo '&lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;#map_canvas&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;548px&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;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;';
	}
}

function carawebs_initialise_googlemaps(){

	if (is_page('69')) {
	    $googlescript = '&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://maps.googleapis.com/maps/api/js?sensor=false&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;';
	    echo $googlescript;
	}
}

function carawebs_googlemaps_control(){

	if (is_page('69')) {

    // Register the control script
    wp_register_script( 'carawebs_googlemap', get_template_directory_uri() . '/assets/js/vendor/google-map.js');

		// Pass variables to the script - this avoids having to hardcode the map marker in javascript
		// This could be a user-selected field
		$imagelocation = get_template_directory_uri() . . '/assets/img/marker.png';
		$site_variables = array(
	    'markerImage' =&amp;gt; $imagelocation
	    );

		wp_localize_script( 'carawebs_googlemap', 'carawebsMapVars', $site_variables );
		// This function makes variables available to carawebs_googlemap
		// Define the image in js like this: var image = (carawebsMapVars.markerImage);

		// Enqueue the map controls
    wp_enqueue_script('carawebs_googlemap');

	}
}


// Add hooks for front-end
add_action('wp_head', 'carawebs_map_style', 1);
add_action('wp_head', 'carawebs_initialise_googlemaps', 2);
add_action('wp_enqueue_scripts', 'carawebs_googlemaps_control', 105);

/*====================================================================*/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;mapscript&quot;&gt;The Google Map Script&lt;/h2&gt;
&lt;p&gt;The following is a sample custom Google map, saved as &lt;code class=&quot;highlighter-rouge&quot;&gt;/assets/js/vendor/google-map.js&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;initialize&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;zoom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;52.693032&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;8.864808&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;mapTypeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MapTypeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ROADMAP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;scrollwheel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;disableDefaultUI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;styles&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;water&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
					&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#3bade2&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;landscape&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#f2e5d4&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;road.highway&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;geometry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#777777&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;road.arterial&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;geometry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#c0c0c0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]},&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//#e4d7c6&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;road.local&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;geometry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#fbfaf7&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;road.highway&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;labels&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&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;s2&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;off&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;transit.line&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;labels.icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&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;s2&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;off&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;poi.park&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;geometry&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#c5dac6&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;administrative&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lightness&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]},{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;road&quot;&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;poi.park&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;elementType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;labels&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
						&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lightness&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&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;s2&quot;&gt;&quot;featureType&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;road&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;stylers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lightness&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&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;nx&quot;&gt;carawebsMap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;map_canvas&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Define an image to be used as a marker&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// var image set from wp_localize_script in the enqeueing function&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carawebsMapVars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;markerImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;


		&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;centreLatLng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;52.693032&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;8.864808&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/* School Co-ordinates */&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennisLatLng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;52.847079&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;8.987698&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Ennis Community College&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennistymon1LatLng&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;52.941578&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;9.289763&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Ennistymon CBS&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/*===============================
      Position the Markers
    ===============================*/&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;marker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennisLatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;icon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Ennis Community College'&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;marker2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennistymon1LatLng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;icon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Ennistymon CBS'&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;cm&quot;&gt;/*===============================
        Content Strings for Markers
      ===============================*/&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;// Ennis Community College&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennisContentString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;div id=&quot;content&quot; style=&quot;color: #666;&quot;&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;h4 id=&quot;firstHeading&quot; class=&quot;firstHeading&quot;&amp;gt;Ennis Community College&amp;lt;/h4&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Ennis Community College&amp;lt;/b&amp;gt; is where we started&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'our first School Cafe. We have been providing a service&amp;lt;br&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'for the staff and students since 2009 -&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'when we converted an old cupboard into a&amp;lt;br&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'fully functioning school canteen.&amp;lt;/p&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;// Ennistymon CBS&lt;/span&gt;
			 	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennistymon1ContentString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;div id=&quot;content&quot; style=&quot;color: #000;&quot;&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				 &lt;span class=&quot;s1&quot;&gt;'&amp;lt;h4 id=&quot;firstHeading&quot; class=&quot;firstHeading&quot;&amp;gt;Ennistymon CBS&amp;lt;/h4&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				 &lt;span class=&quot;s1&quot;&gt;'&amp;lt;div id=&quot;bodyContent&quot;&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				 &lt;span class=&quot;s1&quot;&gt;'&amp;lt;p&amp;gt;Some information about Ennistymon CBS.&amp;lt;/p&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				 &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
				 &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/*===========================
      Set the InfoWindow
    ===========================*/&lt;/span&gt;

			&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennisInfowindow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;InfoWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennisContentString&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

			&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennistymon1InfoWindow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;InfoWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ennistymon1ContentString&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;


			&lt;span class=&quot;cm&quot;&gt;/*===================================
        Click Events for Markers
      ===================================*/&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Ennis Community College&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'click'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;nx&quot;&gt;ennisInfowindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Reference the info window and marker&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Ennistymon CBS&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;marker2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'click'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;nx&quot;&gt;ennistymon1InfoWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;marker2&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;p&quot;&gt;}&lt;/span&gt;

		&lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addDomListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;load&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addDomListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;resize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&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;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			 &lt;span class=&quot;nx&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;resize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			 &lt;span class=&quot;nx&quot;&gt;carawebsMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Mon, 23 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/custom-google-maps/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/custom-google-maps/</guid>
      </item>
      
    
      
      <item>
        <title>Typical Responsive Breakpoints</title>
        <description>&lt;h2 id=&quot;xs&quot;&gt;Extra Small Screens/Phone&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;480px and below&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sm&quot;&gt;Small Screen/Tablet&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;481px to 768px&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;md&quot;&gt;Medium Screen/Desktop&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;769px to 992px&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;lg&quot;&gt;Large Screen/Wide Desktop&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;993px to 1200px&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;xl&quot;&gt;XL Desktop&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;wider than 1200px&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Closely based on &lt;a href=&quot;http://getbootstrap.com/&quot;&gt;Twitter Bootstrap 3.x&lt;/a&gt; breakpoints.&lt;/p&gt;

&lt;p&gt;These breakpoints need not be totally fixed - but they’re a good guide to basic responsive layouts. In particular, an extra breakpoint might be needed at 320px and below. Or alternatively, you could go fully responsive - use inline-block to define columns and make everything &lt;a href=&quot;http://csswizardry.com/2013/02/introducing-csswizardry-grids/&quot;&gt;percentage based&lt;/a&gt;, changing proportions as and when needed based on your design!&lt;/p&gt;
</description>
        <pubDate>Thu, 19 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/typical-responsive-breakpoints/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/typical-responsive-breakpoints/</guid>
      </item>
      
    
      
      <item>
        <title>WordPress CLI</title>
        <description>&lt;p&gt;The WordPress CLI tool allows you to deploy WordPress and add themes &amp;amp; plugins from the command line.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;Change to user that will own the WP install:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@server:~# &lt;/span&gt;su username&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Give proper ownership to a suitable directory and move into it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chown username -R var/www/site.com/public_html
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /var/www/site.com/public_html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Install WP-cli:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo curl -L https://raw.github.com/wp-cli/builds/gh-pages/phar/wp-cli.phar &amp;gt; wp-cli.phar&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make executable, move to make available across system:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/bin/wp&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Get info about wp-cli to check the installation worked:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp --info&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;install-wordpress-using-wp-cli&quot;&gt;Install WordPress Using WP-CLI&lt;/h2&gt;
&lt;p&gt;Create a new directory called “testsite”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mkdir testsite&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Give proper ownership:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo chown -R user:www-data /var/www/testsite&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Download WP core:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp core download&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create a MySQL Database:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql -u root -pROOTPASSWORD -e &lt;span class=&quot;s2&quot;&gt;&quot;create database db_name; GRANT ALL PRIVILEGES ON db_name.* TO new_user@localhost IDENTIFIED BY '12345'&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Configure WordPress to use it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp core config --dbname&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;db_name --dbuser&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;new_user --dbpass&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1234567 --dbhost&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;localhost&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Install WordPress:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp core install --url&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;http://localhost/testsite --title&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Basic Test Site&quot;&lt;/span&gt; --admin_user&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;USERNAME --admin_password&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;STRONGPASSWORD --admin_email&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;USER@WEBSITE.COM&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;using-wp-cli-deploy-plugin&quot;&gt;Using WP-CLI Deploy Plugin&lt;/h2&gt;

&lt;p&gt;Install WP-cli Deploy plugin in relevant WP directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone https://github.com/c10b10/wp-cli-deploy.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create a wp-cli.yml file in the root of you WordPress directory and add this line to the file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;require: &lt;span class=&quot;s2&quot;&gt;&quot;relative/path/to/deploy.php&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;require: &lt;span class=&quot;s2&quot;&gt;&quot;wp-cli-deploy/deploy.php&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Enter &lt;code class=&quot;highlighter-rouge&quot;&gt;wp help deploy&lt;/code&gt; to check it works.&lt;/p&gt;

&lt;p&gt;To use WP-cli deploy, you need to define constants in wp-config.php.&lt;/p&gt;

&lt;p&gt;For example, set up deploy for the “dev” environment:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;    define( 'DEV_URL', 'testsite.com' );
    define( 'DEV_WP_PATH', '/var/www/testsite.com/public_html/' );
    define( 'DEV_HOST', '12.34.567.890' );
    define( 'DEV_USER', 'remote-server-username' );
    define( 'DEV_PORT', '22' );
    define( 'DEV_PATH', '/var/www/testsite.com/public_html' ); # Path to remote site
    define( 'DEV_UPLOADS_PATH', '/var/www/testsite.com/public_html/wp-content/uploads' );
    define( 'DEV_THEMES_PATH', '/var/www/testsite.com/public_html/wp-content/themes' );
    define( 'DEV_PLUGINS_PATH', '/var/www/testsite.com/public_html/wp-content/plugins' );
    define( 'DEV_DB_HOST', 'localhost' );
    define( 'DEV_DB_NAME', 'databaseName' );
    define( 'DEV_DB_USER', 'databaseUser' );
    define( 'DEV_DB_PASSWORD', '1234567goodpassword' );&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Deploy Database and uploads to dev environment:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wp deploy push dev --what&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;db &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; wp deploy push dev --what&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;uploads&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;necessary-local-ownership-local&quot;&gt;Necessary Local Ownership Local&lt;/h2&gt;
&lt;p&gt;Set permissions: allow rwx for user &amp;amp; group, r for others&lt;/p&gt;

&lt;p&gt;Remote Ownership:
Example
drwxr-xr-x  5 USERNAME www-data  4096 May  5 17:20 testsite&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/wp-cli/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/wp-cli/</guid>
      </item>
      
    
      
      <item>
        <title>Set Up WP Development Environment</title>
        <description>&lt;p&gt;This will create a test site here:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/var/www/testdomain.com/public_html/newsite&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The site will be visible at testdomain.com/newsite&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;create-dir&quot;&gt;Create a Directory&lt;/h2&gt;
&lt;p&gt;Open a terminal on the VPS by means of SSH.&lt;/p&gt;

&lt;p&gt;Navigate to the test domain document root:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cd /var/www/testdomain.com/public_html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a new directory:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo mkdir newsite&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;ownership&quot;&gt;Set Ownership &amp;amp; Permissions&lt;/h2&gt;
&lt;p&gt;Grant ownership of the new directory to the proper user. Don’t leave the directory owned by root.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chown -R $USER:www-data /var/www/testdomain.com/public_html/newsite&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Set permissions so files can be viewed:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chmod -R 755 /var/www/testdomain.com/public_html/newsite&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;wordpress-settings&quot;&gt;WordPress Settings&lt;/h2&gt;

&lt;p&gt;Set Directory Permissions to 755:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find /var/www/domain.com/path-to-wp -type d -exec chmod 755 {} \;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Set File Permissions to 644:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find /var/www/path-to-wp -type f -exec chmod 644 {} \;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that permissions may need to be more permissive to allow uploading of files, depending on the server environment:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Any file that needs write access from WordPress should be owned or group-owned by the user account used by the WordPress (which may be different than the server account). For example, you may have a user account that lets you FTP files back and forth to your server, but your server itself may run using a separate user, in a separate usergroup, such as dhapache or nobody. If WordPress is running as the FTP account, that account needs to have write access, i.e., be the owner of the files, or belong to a group that has write access. In the latter case, that would mean permissions are set more permissively than default (for example, 775 rather than 755 for folders, and 664 instead of 644).&lt;/p&gt;

  &lt;p&gt;From WordPress Codex.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create a MySQL Database with new user &amp;amp; password:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql -u root -pROOTPASSWORD -e &quot;create database db_name; GRANT ALL PRIVILEGES ON db_name.* TO new_user@localhost IDENTIFIED BY 'NewUserPassword'&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Entering the root password is optional and may be inadvisable. Leave it out, and the system will prompt for Root password in normal way before carrying out the mysql command.&lt;/p&gt;

&lt;h2 id=&quot;WordPress&quot;&gt;Install WordPress&lt;/h2&gt;
&lt;p&gt;Install WordPress using &lt;a href=&quot;/2014/06/wp-cli/&quot;&gt;WP-CLI&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;aliases&quot;&gt;Set Aliases&lt;/h2&gt;

&lt;p&gt;Open ~/.bashrc and set up aliases:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#####################################################&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Create New Project Site Deploy Aliases&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#####################################################&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Push new project database&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;new-project-pushdb&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/local-site; wp deploy push dev --what=db&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Push new project plugins&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;new-project-pushplug&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/local-site; wp deploy push dev --what=plugins&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Push new project uploads&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;new-project-pushuploads&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/local-site; wp deploy push dev --what=uploads&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Push new project db and uploads&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;new-project-pushdbuploads&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/local-site; wp deploy push dev --what=db &amp;amp;&amp;amp; wp deploy push dev --what=uploads&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#Pull new project db and uploads folder&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;new-project-pullcontent&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cd /var/www/local-site; wp deploy pull dev --what=db &amp;amp;&amp;amp; wp deploy pull dev --what=uploads&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;####### End new project ##############################&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/set-up-dev-environment/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/set-up-dev-environment/</guid>
      </item>
      
    
      
      <item>
        <title>Linux Cheat Sheet</title>
        <description>&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;This cheatsheet contains various terminal commands for Ubuntu, but they should work for any
debian based Linux flavour. Maintained by
&lt;a href=&quot;https://github.com/DavidCWebs&quot;&gt;@DavidCWebs&lt;/a&gt; - get in touch with me &lt;a href=&quot;https://twitter.com/DavidRedBranch&quot;&gt;via
Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;general-commands&quot;&gt;General Commands&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Change Directory&lt;/th&gt;
      &lt;th&gt;Move up one Directory&lt;/th&gt;
      &lt;th&gt;Move to Root&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cd /path/to/dir&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cd..&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cd /&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Move to Users Home&lt;/th&gt;
      &lt;th&gt;Show the directory you’re in&lt;/th&gt;
      &lt;th&gt;Find file whose name starts with “file”, starting from root directory&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cd ~&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pwd&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find / -name 'file*'&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Excellent tool for explaining commands:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://explainshell.com/&quot;&gt;Explainshell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;finding-stuff&quot;&gt;Finding Stuff&lt;/h2&gt;

&lt;p&gt;Use grep to find a string recursively in a directory, output to a file:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grep -r &quot;carawebs_download_link_repeater()&quot; /var/www/thinkup/wp-content/themes/thinkup &amp;gt; thinkup-grep&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;output-file-info-recursively&quot;&gt;Output File Info Recursively&lt;/h2&gt;
&lt;p&gt;Very handy for /wp-content/uploads to track down large files.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find /target-parent-dir -type f -follow -print|xargs ls -l &amp;gt; report&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;get-system-info&quot;&gt;Get System Info&lt;/h2&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Output IP address and other useful bits of info:
ifconfig | grep inet

# Output hostname:
hostnamectl
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;managing-files&quot;&gt;Managing Files &amp;amp; Directories&lt;/h2&gt;

&lt;p&gt;Copy an entire directory and it’s contents, including sub directories &amp;amp; files:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo cp -r /path/to/source /path/to/destination&lt;/code&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Delete Directory&lt;/th&gt;
      &lt;th&gt;Delete directory and contents with no warnings&lt;/th&gt;
      &lt;th&gt;Move file to destination directory&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rm -r dirname&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rm -rf dirname&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mv file.txt destination-dir&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;List all files in a directory&lt;/th&gt;
      &lt;th&gt;Write files &amp;amp; directories list to a file&lt;/th&gt;
      &lt;th&gt;Include hidden files and directories, preceded with “.”&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls -l&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls -LR &amp;gt;&amp;gt; list.txt&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls -a&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;List contents of parent directory&lt;/th&gt;
      &lt;th&gt;Print directory contents to print.txt&lt;/th&gt;
      &lt;th&gt;Remove file1 in current directory&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls ../&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ls &amp;gt; print.txt&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rm file1&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Tree is a directory listing programme that displays files and folders
recursively in a tree structure.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Install Tree&lt;/th&gt;
      &lt;th&gt;Write files/dirs in tree format&lt;/th&gt;
      &lt;th&gt;Tree format with file permissions&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo apt-get install tree&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tree &amp;gt;&amp;gt; inventory.txt&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tree -p &amp;gt;&amp;gt; inventory.txt&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Rename file extensions:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rename 's/\.foo$/\.bar/' * SPECIFIC EXAMPLE: rename 's/\.gddoc$/\.txt/' *
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;managing-groups&quot;&gt;Managing Groups&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;List all groups on system&lt;/th&gt;
      &lt;th&gt;Create new group&lt;/th&gt;
      &lt;th&gt;Add user www-data to group&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cat /etc/group&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo groupadd newgrp&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo adduser www-data newgrp&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;bash-scripts&quot;&gt;BASH Scripts&lt;/h2&gt;

&lt;p&gt;Make /file.sh executable:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo chmod +x /file.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Move to /usr/local/bin, execute in terminal with file.sh&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo mv file.sh /usr/local/bin&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;managing-users&quot;&gt;Managing Users&lt;/h2&gt;

&lt;p&gt;Add User to Sudoers:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo adduser &amp;lt;username&amp;gt; sudo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create user with password and home folder:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo useradd -d /home/testuser -m testuser&lt;/code&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo passwd testuser&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;determine-file-directory-size&quot;&gt;Determine File/Directory Size&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;du&lt;/code&gt; command summarises “Disk Usage”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;By default, the Single Unix Specification (SUS) specifies that du is to display the file space allocated to each file and directory contained in the current directory. Links will be displayed as the size of the link file, not what is being linked to; the size of the content of directories is displayed, as expected.&lt;/p&gt;

  &lt;p&gt;As du reports allocation space and not absolute file space, the amount of space on a file system shown by du may vary from that shown by df if files have been deleted but their blocks not yet freed. Also the minfree setting that allocates datablocks for the filesystem and the super user processes creates a discrepancy between total blocks and the sum of used and available blocks. The minfree setting is usually set to about 5% of the total filesystem size.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Du_(Unix)&quot;&gt;du wikipedia article&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To return directory size (not individually listed content size) in human-readable format (e.g. 3.9G):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;du -hs /path/to/directory
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;du&lt;/code&gt; takes a single argument, specifying a pathname. If no pathname is specified, the current directory is used. &lt;code class=&quot;highlighter-rouge&quot;&gt;du&lt;/code&gt; options:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-a In addition to the default output, include information for each non-directory entry&lt;/li&gt;
  &lt;li&gt;-c display a grand total of the disk usage found by the other arguments&lt;/li&gt;
  &lt;li&gt;-d #, the depth at which summing should occur. -d 0 sums at the current level, -d 1 sums at the subdirectory, -d 2 at sub-subdirectories, etc.&lt;/li&gt;
  &lt;li&gt;-H calculate disk usage for link references specified on the command line&lt;/li&gt;
  &lt;li&gt;-k show sizes as multiples of 1024 bytes, not 512-byte&lt;/li&gt;
  &lt;li&gt;-L calculate disk usage for link references anywhere&lt;/li&gt;
  &lt;li&gt;-s report only the sum of the usage in the current directory, not for each file&lt;/li&gt;
  &lt;li&gt;-x only traverse files and directories on the device on which the pathname argument is specified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other Unix and Unix-like operating systems may add extra options - BSD and GNU du specify a -h option, displaying disk usage in a format easier to read by the user (e.g. 10 MB).&lt;/p&gt;

&lt;h2 id=&quot;WordPress&quot;&gt;WordPress Settings&lt;/h2&gt;

&lt;p&gt;Set Directory Permissions to 755:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find /var/www/domain.com/path-to-wp -type d -exec chmod 755 {} \;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Set File Permissions to 644:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;find /var/www/path-to-wp -type f -exec chmod 644 {} \;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that permissions may need to be more permissive to allow uploading of files, depending on the server environment:&lt;/p&gt;

&lt;p&gt;“Any file that needs write access from WordPress should be owned or group-owned by the user account used by the WordPress (which may be different than the server account). For example, you may have a user account that lets you FTP files back and forth to your server, but your server itself may run using a separate user, in a separate usergroup, such as dhapache or nobody. If WordPress is running as the FTP account, that account needs to have write access, i.e., be the owner of the files, or belong to a group that has write access. In the latter case, that would mean permissions are set more permissively than default (for example, 775 rather than 755 for folders, and 664 instead of 644).”
From &lt;a href=&quot;http://codex.wordpress.org/Changing_File_Permissions&quot;&gt;WordPress Codex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a MySQL Database with new user &amp;amp; password:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql -u root -pROOTPASSWORD -e &quot;create database db_name; GRANT ALL PRIVILEGES ON db_name.* TO new_user@localhost IDENTIFIED BY 'NewUserPassword'&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Entering root password is optional and may be inadvisable. Leave it out, and
the system will prompt for Root password in normal way before carrying out the
mysql command.&lt;/p&gt;

&lt;h2 id=&quot;remote-sync&quot;&gt;Sync to Remote Server&lt;/h2&gt;

&lt;p&gt;This is probably better than scp - since it only transfers the differences
between two sets of files. Assumes that SSH has been set up between local and
remote.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rsync -az /path/to/source username@host:/path/to/destination&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;remote-server-with-non-standard-ssh-port&quot;&gt;Remote Server with Non-Standard SSH Port&lt;/h2&gt;

&lt;p&gt;If connecting on a non-standard SSH port (which you should be doing), set the port in the rsync command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-e &quot;ssh -p 1234&quot;&lt;/code&gt;  where “1234” is the SSH port number.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-e&lt;/code&gt; is the short form of rsh, which specifies the remote shell to use.&lt;/p&gt;

&lt;p&gt;Sample rsync command for SSH port 1234:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;cmd: 'rsync --progress -a -v -rz --checksum --delete -e &quot;ssh -p 1234&quot; _site/ username@12.23.567.89:/var/www/path/to/deploy'&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;rsync-commands&quot;&gt;Rsync Commands&lt;/h2&gt;

&lt;p&gt;May need to specify SSH:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rsync -az -e ssh /path/to/source username@host:/path/to/destination&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Copy the contents of mu-plugins from a dev site to a local copy:
&lt;code class=&quot;highlighter-rouge&quot;&gt;rsync -raz -e &quot;ssh -p 1234&quot; username@1.123.123.1234:/var/www/remote.com/public_html/subdirectory/wp-content/mu-plugins/ /var/www/local-copy/wp-content/mu-plugins&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;HTML version of rsync man page: &lt;a href=&quot;http://rsync.samba.org/ftp/rsync/rsync.html&quot;&gt;http://rsync.samba.org/ftp/rsync/rsync.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Common options used with rsync commands:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;-v : verbose&lt;/li&gt;
  &lt;li&gt;-r : copies data recursively (but don’t preserve timestamps and permission while transferring data&lt;/li&gt;
  &lt;li&gt;-a : archive mode - preserves almost everything - copies files recursively, preserves symbolic links, file permissions, user &amp;amp; group ownerships and timestamps&lt;/li&gt;
  &lt;li&gt;-z : compress file data&lt;/li&gt;
  &lt;li&gt;-h : human-readable, output numbers in a human-readable format&lt;/li&gt;
  &lt;li&gt;–delete : delete files on the destination that do not exist in source&lt;/li&gt;
  &lt;li&gt;–checksum : use checksum instead of timestamps to check whether the directory/site has changed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exclude files from an rsync with &lt;code class=&quot;highlighter-rouge&quot;&gt;--exclude&lt;/code&gt;. To exclude several different types of files, use &lt;code class=&quot;highlighter-rouge&quot;&gt;--exclude&lt;/code&gt; more than once:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rsync -avP --exclude='*.zip' --exclude='*.gz'
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Alternatively, use an exclude file: list each file/directory on a separate line.&lt;/p&gt;

&lt;p&gt;Good description of rsync flags: &lt;a href=&quot;http://lesterchan.net/blog/2011/07/15/rsync-to-
dropbox-jungle-disk/&quot;&gt;http://lesterchan.net/blog/2011/07/15/rsync-
to-dropbox-jungle-disk/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good description of rsync &amp;amp; Jekyll: &lt;a href=&quot;http://www.garron.me/en/blog/using-rsync-with-jekyll.html&quot;&gt;http://www.garron.me/en/blog/using-rsync-with-jekyll.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;rsync-backup&quot;&gt;Rsync from Remote Server&lt;/h2&gt;

&lt;p&gt;Copy directories recursively:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;david@david-desktop:~$ rsync -raz username@12.123.1234.1234:/var/www/ ~/carawebs-server-backups&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Combine this with a MYSQL backup:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mysqldump -u user -ppassword --all-databases &amp;gt; all_databases.sql&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restore from this:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mysql -u user -ppassword &amp;lt; all_databases.sql&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;scp&quot;&gt;Secure Copy to/from Remote Server&lt;/h2&gt;

&lt;p&gt;Copy example.txt from remote machine to local:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;scp your_username@123.12.12.123:example.txt /local/directory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; for the LOCAL machine!&lt;/p&gt;

&lt;h2 id=&quot;scp-non-standard&quot;&gt;SCP with Non-Standard Port Number&lt;/h2&gt;

&lt;p&gt;Copy example.html from local to remote, on a non-standard port:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;scp -P 1234 ~/example.html username@123.123.12.123:/var/www/html/public_html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; to specify port number, SCP needs an uppercase “P” - in contrast to rsync.&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/linux-cheat-sheet/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/linux-cheat-sheet/</guid>
      </item>
      
    
      
      <item>
        <title>Add Font Awesome to Roots</title>
        <description>&lt;p&gt;Font-awesome is a great way to add iconography to a website.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Copy Font Awesome font files to /assets/fonts.&lt;/li&gt;
  &lt;li&gt;Make a new directory called “font-awesome” in assets/less.&lt;/li&gt;
  &lt;li&gt;Add Font Awesome LESS files to the directory assets/less/font-awesome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The file assets/less/font-awesome/font-awesome.less imports all other files.&lt;/p&gt;

&lt;p&gt;Check assets/less/font-awesome/variables.less references the font files properly – relative to the compiled CSS file.&lt;/p&gt;

&lt;p&gt;Open assets/less/app.less and add:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;@import &quot;font-awesome/font-awesome.less&quot;;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this way, the font-awesome rules are brought into the main less file that will be compiled.&lt;/p&gt;

&lt;p&gt;Open Gruntfile.js and add assets/less/font-awesome/*.less to the “watch” task.&lt;/p&gt;

&lt;p&gt;If any watched less files change, the css will be recompiled.&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/font-awesome-roots/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/font-awesome-roots/</guid>
      </item>
      
    
      
      <item>
        <title>Custom Sidebars in Roots</title>
        <description>&lt;h2 id=&quot;custom-sidebars&quot;&gt;Custom Sidebars&lt;/h2&gt;
&lt;p&gt;Register a custom widget area in lib/widgets.php&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
/**
 * Register sidebars and widget Areas
 */
function roots_widgets_init() {
  // Primary Sidebar
  register_sidebar(array(
    'name'          =&amp;gt; __('Primary', 'roots'),
    'id'            =&amp;gt; 'sidebar-primary',
    'before_widget' =&amp;gt; '&amp;lt;section class=&quot;widget %1$s %2$s&quot;&amp;gt;',
    'after_widget'  =&amp;gt; '&amp;lt;/section&amp;gt;',
    'before_title'  =&amp;gt; '&amp;lt;h3&amp;gt;',
    'after_title'   =&amp;gt; '&amp;lt;/h3&amp;gt;',
  ));

  //Secondary Sidebar for courses CPTs
  register_sidebar(array(
    'name'          =&amp;gt; __('Course Sidebar', 'roots'),
    'id'            =&amp;gt; 'sidebar-courses',
    'before_widget' =&amp;gt; '&amp;lt;section class=&quot;widget %1$s %2$s&quot;&amp;gt;',
    'after_widget'  =&amp;gt; '&amp;lt;/section&amp;gt;',
    'before_title'  =&amp;gt; '&amp;lt;h3&amp;gt;',
    'after_title'   =&amp;gt; '&amp;lt;/h3&amp;gt;',
  ));

  //Footer
  register_sidebar(array(
    'name'          =&amp;gt; __('Footer', 'roots'),
    'id'            =&amp;gt; 'sidebar-footer',
    'before_widget' =&amp;gt; '&amp;lt;section class=&quot;widget %1$s %2$s&quot;&amp;gt;',
    'after_widget'  =&amp;gt; '&amp;lt;/section&amp;gt;',
    'before_title'  =&amp;gt; '&amp;lt;h3&amp;gt;',
    'after_title'   =&amp;gt; '&amp;lt;/h3&amp;gt;',
  ));

  // Widgets
  register_widget('Roots_Vcard_Widget');
}
add_action('widgets_init', 'roots_widgets_init');
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Amend templates/sidebar.php so that the custom sidebar is delivered for the appropriate content types. In this example, the custom sidebar id “sidebar-courses” is associated with the sfwd-courses CPT:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php  
if ( is_singular('sfwd-courses') ) :
  dynamic_sidebar('sidebar-courses');
else:
  ?&amp;gt;&amp;lt;div class=&quot;bottom-pad&quot;&amp;gt;&amp;lt;?php get_search_form(); ?&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;?php
  dynamic_sidebar('sidebar-primary');
endif;  
?&amp;gt;
&amp;lt;?php dynamic_sidebar('sidebar-secondary'); ?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/custom-sidebar-roots/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/custom-sidebar-roots/</guid>
      </item>
      
    
      
      <item>
        <title>Download A Website Using wget</title>
        <description>&lt;p&gt;Use the wget command line utility to download an entire website.&lt;/p&gt;

&lt;p&gt;Be careful with recursive retrieval - you might download the entire internet!&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget \
     --recursive \
     --no-clobber \
     --page-requisites \
     --html-extension \
     --convert-links \
     --domains testsite.com \
     --no-parent \
         http://testsite.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;–recursive: downloads entire site&lt;/li&gt;
  &lt;li&gt;–no-clobber: doesn’t overwrite files, useful for interrupted downloads&lt;/li&gt;
  &lt;li&gt;–page-requisites: download all the files required to display the page (CSS, images etc)&lt;/li&gt;
  &lt;li&gt;–html-extension: save files with extension HTML&lt;/li&gt;
  &lt;li&gt;–convert-links: make links relative so they work off-line&lt;/li&gt;
  &lt;li&gt;–domains: Set domains to be followed&lt;/li&gt;
  &lt;li&gt;–no-parent: Don’t ascend to the parent directory when retrieving recursively - guarantees that only the files below a certain hierarchy will be downloaded&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;alternative-method&quot;&gt;Alternative Method&lt;/h2&gt;
&lt;p&gt;This can sometimes works better:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget --wait=20 --limit-rate=20K -r -p -U Mozilla http://www.testsite.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Friendlier on the target website and avoids getting blocked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: We use this primarily for downloading our own or our client’s CMS based sites in “flat” HTML - so we’re only hitting our own site resources, or we’re downloading with permission.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re using this method to download other people’s websites, be responsible.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;http://www.gnu.org/software/wget/manual/wget.html&quot;&gt;wget man page&lt;/a&gt; for more details.&lt;/p&gt;
</description>
        <pubDate>Sun, 08 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/download-entire-site-as-flat-html/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/download-entire-site-as-flat-html/</guid>
      </item>
      
    
      
      <item>
        <title>Second Dropbox on Ubuntu 14.04</title>
        <description>&lt;p&gt;Create two instances of Dropbox on one machine. This will allow a separate Dropbox to be run, which can help keep managed client backups rational.&lt;/p&gt;

&lt;h2 id=&quot;setup-directories&quot;&gt;Setup Directories&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mkdir .name-dropbox&lt;/code&gt;: This will contain Dropbox configuration settings.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mkdir name-dropbox&lt;/code&gt;: This will contain the Dropbox folder.&lt;/p&gt;

&lt;p&gt;Open a terminal and enter:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;HOME=$HOME/.name-dropbox /usr/bin/dropbox start -i&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will start the Dropbox setup window. Select a customised location for Dropbox by ticking “I want to choose where to put my Dropbox folder”, which should be located in &lt;code class=&quot;highlighter-rouge&quot;&gt;/name-dropbox&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;make-a-control-script&quot;&gt;Make a Control Script&lt;/h2&gt;

&lt;p&gt;To control the second Dropbox, create a BASH script.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo nano ~/DropboxAltStarter.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Paste:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/.name-dropbox /usr/bin/dropbox start
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Make this script executable:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;chmod +x ~/DropboxAltStarter.sh&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;start-the-second-dropbox-on-startup&quot;&gt;Start the Second Dropbox on Startup&lt;/h2&gt;
&lt;p&gt;Type “Start” into Ubuntu dash, access “Startup Applications”.&lt;/p&gt;

&lt;p&gt;Create a new application with an appropriate name.&lt;/p&gt;

&lt;p&gt;Paste the following as a command, replace “Username”:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/home/Username/DropboxAltStarter.sh&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Jun 2014 09:38:44 +0000</pubDate>
        <link>
        https://dev-notes.eu/2014/06/setup-2nd-dropbox-ubuntu/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/setup-2nd-dropbox-ubuntu/</guid>
      </item>
      
    
      
      <item>
        <title>Jekyll Push to gh-pages Branch</title>
        <description>&lt;p&gt;Make a sub-directory that contains a Jekyll site available at the gh-pages branch of a GitHub repo.&lt;/p&gt;

&lt;p&gt;The site will then be available at http://USERNAME.github.io/REPONAME/&lt;/p&gt;

&lt;p&gt;To begin with, set up an empty Repo. Don’t add a README.md when prompted.&lt;/p&gt;

&lt;p&gt;Initialise git in the local project directory, and connect to the new repo.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd project-directory
git init
git remote add origin https://github.com/USERNAME/REPONAME.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;initial-commit&quot;&gt;Initial Subtree Commit&lt;/h2&gt;
&lt;p&gt;The local Jekyll site is built to the _site directory.&lt;/p&gt;

&lt;p&gt;We need to tell git about the sub-directory and make an initial commit:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git add _site &amp;amp;&amp;amp; git commit -m &quot;Initial _site subtree commit&quot;&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;push-to-gh-pages&quot;&gt;Push to gh-pages&lt;/h2&gt;
&lt;p&gt;Send _site to the gh-pages branch on GitHub&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git subtree push --prefix _site origin gh-pages&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;ongoing&quot;&gt;Push Ongoing Changes&lt;/h2&gt;
&lt;p&gt;Push all changes to the master branch:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git add -A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git commit -m &quot;commit message&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Push changes to the gh-pages branch:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git subtree push --prefix _site origin gh-pages&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Jun 2014 00:00:00 +0100</pubDate>
        <link>
        https://dev-notes.eu/2014/06/push-jekyll-site-to-gh-pages/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2014/06/push-jekyll-site-to-gh-pages/</guid>
      </item>
      
    
      
      <item>
        <title>Using the Web Icons</title>
        <description>&lt;p&gt;This template uses &lt;a href=&quot;http://typicons.com/&quot;&gt;Typicons&lt;/a&gt; web font, provided by &lt;a href=&quot;http://fontello.com/&quot;&gt;Fontello&lt;/a&gt; font bundling service. It allows you to quickly
add nice icons into your pages by using css tags.&lt;/p&gt;

&lt;p&gt;To add an icon somewhere in the template simply do:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;i&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon-home&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will insert a home icon, just as the one seen in the sidebar. The available class names you can use are as follows:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/resources/img/icons.png&quot; alt=&quot;Available Icons&quot; title=&quot;Available Icons&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These should work in all the browsers, all the way down to and including IE7, but not IE6.&lt;/p&gt;

</description>
        <pubDate>Thu, 19 Jan 2012 00:00:00 +0000</pubDate>
        <link>
        https://dev-notes.eu/2012/01/using-web-icons/</link>
        <guid isPermaLink="true">https://dev-notes.eu/2012/01/using-web-icons/</guid>
      </item>
      
    
  </channel>
</rss>
