<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Indie Folk]]></title><description><![CDATA[Some sweet JS and css notes from a front end developer.

Find me at https://github.com/indiefolk and on twitter: @johnlund]]></description><link>http://blog.indiefolk.co.uk/</link><generator>Ghost 0.5</generator><lastBuildDate>Fri, 03 Apr 2026 22:31:55 GMT</lastBuildDate><atom:link href="http://blog.indiefolk.co.uk/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Unit Testing React with Jest and Enzyme]]></title><description><![CDATA[<p>Sometimes it's hard to remember what the right way to do things with Jest &amp; Enzyme are. Here are some questions and code samples to refer to when I (inevitably) get stuck.</p>

<h2 id="howcaniseewhatthefunkisgoingon">How can I see what the funk is going on?</h2>

<p>Use <code>.debug()</code> to get an HTML-like string of a wrapper.</p>

<p>You can then use <code>console.log</code> to view this output - handy for debugging issues with tests.</p>

<pre><code>console.log(component.debug());  
</code></pre>

<h2 id="howdoitestclassmethods">How do I test Class methods?</h2>

<p>To test internal class methods we can use <strong><code>.instance()</code></strong>.</p>

<p>Take the following component</p>

<pre><code>class Button extends Component {  
    constructor(props) {
        super(props);
        this.state = {
            toggle: false
        };
    }

    updateToggle = () =&gt; { 
        this.setState({
            toggle: !toggle
        });
    }

    getDoubled(value) {
        return value * 2;
    }

    render() {
        return &lt;button onClick={this.updateToggle} /&gt;
    }
}
</code></pre>

<p>To test <code>updateToggle</code>, in <code>Button.spec.js</code> we need to use <strong><code>.instance()</code></strong>.</p>

<pre><code>test('updateToggle should update the state correctly', () =&gt; {  
    const component = shallow(&lt;Button /&gt;);

    const instance = component.instance();
    instance.updateToggle();

    expect(instance.state.toggle).toEqual(true);
});
</code></pre>

<p>To test that a method/function returns the expected value you can call it in a similar way:</p>

<pre><code>test('getDoubled returns a value doubled', () =&gt; {  
    const component = shallow(&lt;Button /&gt;);

    const instance = component.instance();
    const value = instance.getDoubled(2);

    expect(value).toEqual(4);
});
</code></pre>]]></description><link>http://blog.indiefolk.co.uk/unit-testing-react-with-jest-and-enzyme/</link><guid isPermaLink="false">3667bd15-61d2-4b22-99a1-4641cf3b704f</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Mon, 08 Jul 2019 13:32:27 GMT</pubDate></item><item><title><![CDATA[CSS Colour Audit]]></title><description><![CDATA[<blockquote>
  <p>or css color audit, for those in the US</p>
</blockquote>

<p>Based on article by A list apart - <a href="http://alistapart.com/article/css-audits-taking-stock-of-your-code">CSS Audits: Taking stock of your code</a>.</p>

<p>While working on a site refactor I found these tools useful in auditing the CSS colour values being used throughout a large e-commerce site.</p>

<h5 id="csscolorguard">CSS Colorguard</h5>

<p><a href="https://github.com/SlexAxton/css-colorguard">https://github.com/SlexAxton/css-colorguard</a></p>

<p>Run the node app against your css file(s) and get a list of colour similarity issues. Uses some complex maths to compare hex values.</p>

<h5 id="combotester">Combotester</h5>

<p><a href="http://www.colorcombos.com/combotester.html">http://www.colorcombos.com/combotester.html</a> <br>
Add as many colours as you need and compare side-by-side. Useful to see large colour swatches for comparison.</p>

<h5 id="hextractor">Hextractor</h5>

<p><a href="https://hex.corvidworks.com/">https://hex.corvidworks.com/</a></p>

<p>Paste your generated css into the input field to get a visual list of all the colours you're using plus hex codes. Handy to visually compare.</p>]]></description><link>http://blog.indiefolk.co.uk/css-colour-audit/</link><guid isPermaLink="false">92881665-aebe-4e0e-be65-cf745b0ac3f4</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Mon, 15 Feb 2016 18:14:53 GMT</pubDate></item><item><title><![CDATA[Git rebase guide]]></title><description><![CDATA[<p><a href="https://speakerdeck.com/ewoodh2o/a-sane-git-workflow">https://speakerdeck.com/ewoodh2o/a-sane-git-workflow</a></p>

<p>Slide 41 onwards has a great explanation of rebase.</p>

<p>If you're on a feature branch, use git rebase to get all the changes from the main branch.</p>

<p>These will be added to your feature branch behind all your commits - your work remains the most recent items on your branch.</p>]]></description><link>http://blog.indiefolk.co.uk/git-rebase-guide/</link><guid isPermaLink="false">863b0f4d-ed97-4dac-80a7-eae127ccf5da</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Wed, 10 Feb 2016 10:05:26 GMT</pubDate></item><item><title><![CDATA[Git overwrite master with <my_branch_name>]]></title><description><![CDATA[<p>It may be useful to replace all the code on <code>master</code> with another branch you've been working on. Depending on what you want to keep on master there are a couple of ways of doing this.</p>

<p>In these examples we will replace <code>master</code> with the content on <code>develop</code></p>

<h3 id="maintainmasterhistory">Maintain <code>master</code> history</h3>

<p>You want to keep your previous progress on <code>master</code>, just move all code from <code>develop</code> across and wipe over the files on <code>master</code>.</p>

<pre><code>git checkout develop 
git merge -s ours master
git checkout master 
git merge develop
</code></pre>

<h3 id="replacemastercompletely">Replace <code>master</code> completely</h3>

<p>It's all gone wrong and you just want to wipe over master.</p>

<pre><code>git checkout develop
git push -f origin master
</code></pre>]]></description><link>http://blog.indiefolk.co.uk/git-overwrite-master-with-my_branch_name/</link><guid isPermaLink="false">e5a80485-375f-4241-a360-7f09617b7238</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Thu, 17 Dec 2015 16:14:52 GMT</pubDate></item><item><title><![CDATA[Flexbox notes]]></title><description><![CDATA[<p>A few notes and good sites on explaining Flexbox, because I really don't get it sometimes.</p>

<p><a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">CSS Tricks: A simple guide to Flexbox</a></p>

<p>To achieve a card layout: <br>
<a href="http://chriswrightdesign.com/experiments/using-flexbox-today/?mc_cid=c95a03a2f4&amp;mc_eid=fc4922793a#card-layout">Using Flexbox Today - Flexbox layouts - Card layout</a></p>

<p><a href="https://philipwalton.github.io/solved-by-flexbox/?mc_cid=c95a03a2f4&amp;mc_eid=fc4922793a">Solved by Flexbox</a></p>]]></description><link>http://blog.indiefolk.co.uk/flexbox-notes/</link><guid isPermaLink="false">17905000-2cb7-4d5b-a4c8-71ae040598ae</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Fri, 16 Oct 2015 14:28:31 GMT</pubDate></item><item><title><![CDATA[Get current directory path within a Grunt plugin using __dirname]]></title><description><![CDATA[<p>If you need to refer to files within a grunt plugin you can use <code>__dirname</code>.</p>

<p>I've used this to grab template files in a different directory within my grunt plugin, so that I can use them within the main task file.</p>

<p>e.g. <br>
In this setup:</p>

<pre><code>/grunt-plugin-PLUGIN_NAME
--/tasks
---- PLUGIN_NAME.js
--/templates
---- template.js
---- template.hbs
---- template.css
</code></pre>

<p>from a task within <code>PLUGIN_NAME.js</code> you could retrieve the content of template.hbs with</p>

<pre><code>var template = __dirname + '/../templates/template.hbs';
</code></pre>]]></description><link>http://blog.indiefolk.co.uk/get-current-path-within-grunt-plugin/</link><guid isPermaLink="false">727b21db-1255-4445-ac3e-61dc05836638</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Wed, 22 Jul 2015 15:37:30 GMT</pubDate></item><item><title><![CDATA[Marionette vent workflow]]></title><description><![CDATA[<p>Here are some notes on useful workflows when using the Backbone Marionette <code>vent</code> event manager.</p>

<h2 id="grouppagewideevents">Group page-wide events</h2>

<p>When working in a modular way you may find you are writing the same event handler code in many different places:</p>

<pre><code>$('window').on('resize', function () {
    // Do some resize code here
});
</code></pre>

<p>Instead of repeating this same window binding many times you can bind just once to the jQuery event and then make use of event triggers in each of your modules to run different code:</p>

<p>app.js</p>

<pre><code>// Bind to jQuery events e.g. Window resize event
$('window').on('resize', function () {
    vent.trigger('window:resize');
});
</code></pre>

<p>childModuleA.js</p>

<pre><code>this.listenTo('vent' 'window:resize', handleResizeFunction);
...
function handleResizeFunction () {
    // Do a thing on resize
});
</code></pre>

<p>childModuleB.js</p>

<pre><code>this.listenTo('vent' 'window:resize', handleResizeDifferentlyFunction);
...
function handleResizeDifferentlyFunction () {
    // Do something else on resize here
});
</code></pre>

<p>I find this a useful way of grouping quite standard functionality together. You can apply the same principle to all kinds of other events.</p>]]></description><link>http://blog.indiefolk.co.uk/marionette-vent-workflow/</link><guid isPermaLink="false">49fb06fd-b3d1-42e3-bb80-a0551e77a6c0</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Wed, 08 Jul 2015 13:35:00 GMT</pubDate></item><item><title><![CDATA[Responsive images with fixed aspect ratio using intrinsic sizing]]></title><description><![CDATA[<p>Based on the now quite vintage <a href="http://alistapart.com/article/creating-intrinsic-ratios-for-video">A List Apart</a> article from 2009, which looks at <a href="http://alistapart.com/d/creating-intrinsic-ratios-for-video/example2.html">maintaining a video aspect ratio</a> on resize, you can do the same for responsive images.</p>

<p>To achieve this we place our responsive image in a container element. By setting the <code>padding-bottom</code> of this element to a percentage which matches the image's aspect ratio you'll ensure that it stays the same size.</p>

<p>To calculate this percentage just divide the natural width of your image by it's height and multiply by 100 to find the correct padding-bottom.</p>

<h3 id="example">Example</h3>

<h4 id="markup">Markup</h4>

<pre><code>&lt;div class="image-wrapper"&gt;
    &lt;img class="responsive-image" src="/path/to/img.jpg" /&gt;
&lt;/div&gt;
</code></pre>

<h4 id="css">CSS</h4>

<pre><code>.image-wrapper {
    position: relative;
    padding-bottom: 20%;
}

.responsive-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;    
}
</code></pre>

<p>Here we've set the padding bottom to <code>20%</code> to replicate a ratio of 1:5 - our image would be 5 times as wide as it is tall. We could use:</p>

<pre><code>padding-top: 56.25%;
</code></pre>

<p>to apply a 16:9 ratio (9 / 16 = 0.5625).</p>

<h3 id="credits">Credits</h3>

<p>Thanks to <a href="https://twitter.com/ihart">@ihart</a> and <a href="http://richardhallows.com/">Rich Hallows</a> for passing on this technique.</p>]]></description><link>http://blog.indiefolk.co.uk/responsive-images-with-fixed-aspect-ratio-using-intrinsic-sizing/</link><guid isPermaLink="false">ce83ad63-f568-4d20-9d9c-afc7d7ecc017</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Fri, 05 Jun 2015 08:02:27 GMT</pubDate></item><item><title><![CDATA[Create users with artisan tinker]]></title><description><![CDATA[<p>Sometimes I need to quickly create a user for admin tasks or to test authentication stuff. Thanks to <a href="https://laracasts.com/lessons/auth-essentials">Auth Essentials - Jeffrey Way's Laracasts</a> for explaining it, this is really easy to do.</p>

<p>Assuming you have your user table already set up, open the <code>tinker</code> command line tool</p>

<pre><code>php artisan tinker
</code></pre>

<p>Create a new user (use whatever fields you need e.g. <code>username</code>, <code>email</code>)</p>

<pre><code>$user = new User;
$user-&gt;username = 'admin';
$user-&gt;name = 'admin';
$user-&gt;password = Hash::make('password');
$user-&gt;save();
</code></pre>

<p>That's it!</p>]]></description><link>http://blog.indiefolk.co.uk/laravel-4-create-users-with-artisan-tinker/</link><guid isPermaLink="false">2aa1fd52-30b8-4bd8-b7f7-7fd317bc8267</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Mon, 19 Jan 2015 11:19:52 GMT</pubDate></item><item><title><![CDATA[Create sites on linode server with bash script]]></title><description><![CDATA[<p>I've found myself doing the same set of tasks every time I want to set up a new website on my Linode server, so I thought I'd turn it into a simple bash script that you keep on the server and run whenever you need to do this.</p>

<p>I've followed the standard instructions from <a href="https://www.linode.com/docs/websites/hosting-a-website">linode's hosting a website docs</a> which are excellent. The script just replaces the <code>example.com</code> entries with a domain that you pass in as a parameter - it's really easy.</p>

<h2 id="setupbashscript">Set up bash script</h2>

<p>First log into your linode server</p>

<p>Then create a new script file</p>

<pre><code>sudo vim new-site.sh
</code></pre>

<p>In this file paste the following</p>

<pre><code>#!/bin/bash

# Add a new site

# If you've got a domain and you want to set up a new site with it
# run this script and pass the new domain as a parameter without a subdomain
# e.g ./new-site.sh -url google.com

# Get address from paramter
DOMAIN=$1
# Set www root directory
wwwroot="/var/www/"

# Create directories
mkdir $wwwroot$DOMAIN

mkdir $wwwroot$DOMAIN/public_html
mkdir $wwwroot$DOMAIN/backups
mkdir $wwwroot$DOMAIN/log

# Create virtual host
cat &gt; /etc/apache2/sites-available/$DOMAIN.conf &lt;&lt; EOF

# domain: $DOMAIN
# public: $wwwroot$DOMAIN/public_html/

&lt;VirtualHost *:80&gt;
  # Admin email, Server Name (domain name), and any aliases
  ServerAdmin webmaster@$DOMAIN
  ServerName  www.$DOMAIN
  ServerAlias $DOMAIN

  # Index file and Document Root (where the public files are located)
  DirectoryIndex index.html index.php
  DocumentRoot $wwwroot$DOMAIN/public_html
  # Log file locations
  LogLevel warn
  ErrorLog  $wwwroot$DOMAIN/log/error.log
  CustomLog $wwwroot$DOMAIN/log/access.log combined
&lt;/VirtualHost&gt;
EOF

# Enable new site
a2ensite $DOMAIN.conf

# Finally restart apache
service apache2 restart
</code></pre>

<p>then save the file and close vim</p>

<pre><code>:wq
</code></pre>

<p>All done!</p>

<h3 id="runnewsitescript">Run new site script</h3>

<p>To run it just type</p>

<pre><code>sudo ./new-site.sh [domain_name]
</code></pre>

<p>e.g.</p>

<pre><code>sudo ./new-site.sh pitchfork.com
</code></pre>

<p>All directories should be set up for you and apache restarted. Assuming you've set up the DNS correctly you should then be able to see your new site in your browser.</p>]]></description><link>http://blog.indiefolk.co.uk/create-sites-on-linode-server-with-bash-script/</link><guid isPermaLink="false">e04fbabc-9d32-4240-8d35-a695a9f2bfc7</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Fri, 16 Jan 2015 10:52:43 GMT</pubDate></item><item><title><![CDATA[Basic HTTP Auth]]></title><description><![CDATA[<p>To protect a site behind basic HTTP Authentication</p>

<h4 id="usingvhosts">Using vhosts</h4>

<pre><code>&lt;Directory "/var/www/[path_to_site]"&gt;
    AllowOverride All
&lt;/Directory&gt;
&lt;Location /&gt;
    AuthType Basic
    AuthUserFile /srv/auth/.htpasswd
    AuthName "Enter details to log in"
    Require valid-user
  &lt;/Location&gt;
</code></pre>

<p>Then create the /srv/auth/.htpasswd file which stores the user/password combo:</p>

<pre><code>htpasswd -c /srv/auth/.htpasswd [user_name]
</code></pre>

<p>Enter your password and it's saved. Restart apache to complete the process.</p>

<p>If you have an existing file, omit the <code>-c</code> option. The <code>-b</code> option allows you to enter the password as the last parameter of the command, as in this example :</p>

<pre><code>htpasswd -b /srv/auth/.htpasswd username pa55w0rd
</code></pre>

<p>See <a href="https://www.linode.com/docs/websites/authbased-access-control-with-apache#generating-http-auth-passwords">Linode Docs</a> for more details.</p>]]></description><link>http://blog.indiefolk.co.uk/basic-http-auth/</link><guid isPermaLink="false">ed368a55-442d-4ac9-8dab-e610786dbfff</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Tue, 06 Jan 2015 14:18:58 GMT</pubDate></item><item><title><![CDATA[Ubuntu 14.04 nodejs and node conflicting]]></title><description><![CDATA[<p>When trying to run commands on an ubuntu 14.04 server I was getting issues trying to install npm modules like pm2 and forever.</p>

<p>The issue seemed to be related to the <code>nodejs-legacy</code> package available via <code>apt-get</code> which didn't really work very well.</p>

<p>I ended up uninstalling this and manually installing node via these instructions:</p>

<pre><code>sudo apt-get update
sudo apt-get --yes --force-yes install git
sudo apt-get --yes --force-yes install build-essential openssl libssl-dev pkg-config
wget http://nodejs.org/dist/v0.10.31/node-v0.10.31.tar.gz
tar zxvf node-v0.10.31.tar.gz
cd node-v0.10.31
sudo ./configure
sudo make
sudo make install
sudo npm install -g forever
sudo rm -rf ~/.npm
</code></pre>

<blockquote>
  <p>from <a href="https://www.digitalocean.com/community/questions/ubuntu-repo-nodejs-require-symlink-to-node-to-use-forever">https://www.digitalocean.com/community/questions/ubuntu-repo-nodejs-require-symlink-to-node-to-use-forever</a></p>
</blockquote>]]></description><link>http://blog.indiefolk.co.uk/ubuntu-14-04-nodejs-and-node-conflicting/</link><guid isPermaLink="false">bd7c118f-dbc3-42e2-b045-4eccbfef8402</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Fri, 26 Sep 2014 12:39:54 GMT</pubDate></item><item><title><![CDATA[Running Ghost as a service]]></title><description><![CDATA[<p>Once you have a ghost blog set up it's quite easy to get it running with the usual command:</p>

<pre><code>npm start --production
</code></pre>

<p>However the blog will stop running as soon as you close your ssh session. To fix this you can add ghost as a service, which gives you further control over the blog and automates restarts should your server restart or node server crash.</p>

<p>To set this up first create a service file for it (where <code>&lt;blog_name&gt;</code> is your blog):</p>

<pre><code>sudo vim /etc/init/&lt;blog_name&gt;-ghost.conf
</code></pre>

<p>Next, edit this file and add the following: <br>
Be sure to replace <code>&lt;blog_name&gt;</code> and <code>&lt;path_to_blog&gt;</code> with your details</p>

<pre><code>#/etc/init/&lt;blog_name&gt;ghost.conf
description "Ghost Blog"
author "Full Name"
# Start the service after everything loaded
start on (local-filesystems and net-device-up IFACE=eth0)
stop on shutdown
# Automatically restart service
respawn
respawn limit 99 5
script
    # Navigate to your app directory
    cd /var/www/&lt;path_to_blog&gt;/public_html

    # Run the script with Node.js and output to a log
    export NODE_ENV=production
    exec /usr/local/bin/npm start /var/www/&lt;path_to_blog&gt;/public_html 2&gt;&amp;1 &gt;&gt; /var/www/&lt;path_to_blog&gt;/log/ghost.log
end script
</code></pre>

<p>Then control the service using:</p>

<pre><code>sudo service ghost start
sudo service ghost stop
sudo service ghost restart
sudo service ghost status
</code></pre>

<p>All done!</p>

<blockquote>
  <p>Credit due to:</p>
  
  <p><a href="https://ghost.org/forum/using-ghost/453-stupid-question-how-do-i-keep-ghost-running/10/">https://ghost.org/forum/using-ghost/453-stupid-question-how-do-i-keep-ghost-running/10/</a>
  <a href="http://ghost.pellegrom.me/installing-ghost-on-ubuntu/">http://ghost.pellegrom.me/installing-ghost-on-ubuntu/</a></p>
</blockquote>]]></description><link>http://blog.indiefolk.co.uk/running-ghost-as-a-service/</link><guid isPermaLink="false">cd0900db-bce7-4d7d-9627-0c9eb013949b</guid><dc:creator><![CDATA[John]]></dc:creator><pubDate>Fri, 26 Sep 2014 12:24:29 GMT</pubDate></item></channel></rss>