Commit dd4438f2 authored by Mike Street's avatar Mike Street
Browse files

Continue content audit

parent d8915560
---
title: Chilly's Dip
date: 2011-05-19
updated: 2016-04-08
intro: I found this in an old recipe book I found in a charity shop. Not quite sure what happened to it, but I've tweaked the recipe and named it after my wife!
permalink: "blog/chillys-dip/"
tags:
- General
- Cooking
---
_I found this in an old recipe book I found in a charity shop. Not quite sure what happened to it, but I've tweaked the recipe and named it after my wife!_
Great dip to go with anything including crisps, burgers or anything else you can dip!
**Ingredients:**
- 6 tomatoes - peeled and finely chopped
- 1 small onion - finely chopped
- 1 sweet red pepper - finely chopped
- 100ml wine vinegar
- 100g caster sugar
- 1 tsp salt
**Method:**
Chuck everything in a saucepan until it’s reduced - normally for about half an hour. Does about a jars worth which keeps in the fridge. Best when the tomatoes aren’t too juicy or if they are, tip the juice away before putting in the saucepan.
Chillis can be added for a bit of heat if desired.
......@@ -3,6 +3,7 @@ title: A world without the web
date: 2013-02-21
updated: 2016-04-08
intro: For those of you that know me, you would be aware that I have recently moved house. For those of you that don't, I have recently moved house.
permalink: "blog/a-world-without-the-web/"
tags:
- General
- Ramblings
......
---
title: Compiling Less on the Command Line
date: 2013-10-19
updated: 2016-04-09
intro: We have been using LESS for a while now, but our process involved including the less.js in the header during development, compiling the LESS using an app before launch and then maintaining the site using the css.
permalink: "blog/compiling-less-on-the-command-line/"
tags:
- Web
- Command Line
- CSS
- Less
---
We've recently changed the way we operate at Bozboz with regards to front-end development.
We have been using LESS for a while now, but our process involved including the less.js in the header during development, compiling the LESS using **Crunch App** before launch and then maintaining the site using the css.
I have been looking at ways we can compile the less on save, use the CSS and maintain the site using the LESS. This isn't anything new and i'm not making out I have discovered a new groundbreaking technique. However, our situation is slightly different. As i've mentioned before, we have dev servers which aren't on our local machines.
The first one I settled on was a slightly modified version of a simple less compile script - [Dead Simple LESS Watch Compiler](https://github.com/jonycheung/deadsimple-less-watch-compiler)
The trouble with this, is it doesn't recursively search folders, and you have to specify an entry and exit point for the LESS/CSS. Looking at the server processing, it also just scans the folder at a set interval - I modified the original from 500 milliseconds to 200 milliseconds - but there was a noticeable delay and a very very _minor_ overhead.
After some more research and more googling, I eventually found a blog post from [Rob Flaherty](http://www.ravelrumba.com/blog/watch-compile-less-command-line/). Unusually, it wasn't actually his blog content I was interested, but the 'Bonus' tweet from [@yoavweiss](http://www.twitter.com/yoavweiss).
I took his original solution and modified it heavily. This original script would compile all LESS sheets found, even when you save one. The modified version now only compiles the one you've saved.
It also finds all the LESS files from your current location, meaning we can run it from the `/home` on our linux dev servers and not have to stop if we change projects - the perfect solution!
[LessWatch](https://gitlab.com/mikestreety/less-watch)
......@@ -3,6 +3,7 @@ title: A placeholder mixin - for Less and Scss
date: 2013-10-23
updated: 2016-04-09
intro: Creating a Less mixin to style input placeholders without using an autoprefixer
permalink: "blog/a-placeholder-mixin-for-less-and-scss/"
tags:
- Web
- CSS
......
......@@ -3,6 +3,7 @@ title: Be a Better Road User
date: 2014-02-18
updated: 2016-04-09
intro: I've been cycling since I can remember, and driving since 2009. Over the last few years, I've believed something more and more and I would like to make a bold statement - Cyclists make better drivers, drivers make better cyclists
permalink: "blog/be-a-better-road-user"
tags:
- General
- Ramblings
......
......@@ -3,6 +3,7 @@ title: A basic SCSS compilation gulpfile.js
date: 2014-03-17
updated: 2019-03-27
intro: This post introduces how to compile SCSS with Gulp along with some core concepts
permalink: "blog/a-simple-sass-compilation-gulpfile-js/"
tags:
- Web
- CSS
......
---
title: An Introduction to CSS Preprocessors
date: 2014-03-24
updated: 2017-06-22
intro: Writing and updating CSS can be a repetitive, tedious and arduous task - especially for big projects. CSS preprocessors can help with that - amalgamating related styles and helping you make your style sheets more DRY
permalink: "blog/an-introduction-to-css-preprocessors/"
tags:
- Web
- CSS
---
Writing and updating CSS can be a repetitive, tedious and arduous task - especially for big projects. CSS preprocessors can help with that - amalgamating related styles and helping you make your style sheets more **DRY** (Don’t Repeat Yourself).
We have been using CSS Preprocessors for quite some time now - first starting with off with [Less](http://lesscss.org/) and recently moving on to [Sass](http://sass-lang.com/) (there is also [Stylus](http://learnboost.github.io/stylus/) as an alternative - but that won’t be covered in this article).
## What is a Preprocessor?
A preprocessor allows the front-end developers to be more programmatic when it comes to styling. It allows us to take advantage of things such as functions and variables, to make our css more DRY.
CSS doesn't natively support these variables or mixins, so we need to use a preprocessor to ‘compile’ the files into browser-readable style sheets. Different processors do it different ways, Sass uses Ruby while Less uses Javascript to compile.
Preprocessors can also compress the CSS output, meaning you can write and develop in expanded CSS knowing that the user is getting the smallest style sheet file size possible. To give an example, the Sass sheets in our latest project add up to _112kb_ - not huge, but big in comparison to the _32kb_ they compress down to.
## Setting Up
Depending on your poison and workflow setting up a preprocessor can, potentially, be very simple.
If you develop your sites locally on your machine there is a myriad of applications you can use to compile and spit out the CSS the other end. [Web resources depot](http://www.webresourcesdepot.com/desktop-compiler-for-less-sass-compass-and-coffeescript-koala/) has a good list, but even a good old [Google Search](https://www.google.co.uk/#q=desktop+sass+and+less+compilers) turns up plenty of options.
If you don’t have this option available to you, then there is a bit more of a manual set-up involved.
With Less, you can [embed the JavaScript file](http://lesscss.org/#using-less-third-party-tools) in the header of your website. This is great for quick, initial set-up but should never be used for a production (live site) environment as this requires the user to have JavaScript enabled and a fast connection to ensure they don’t see a Flash Of Unstyled Content (FOUC). It also slows down the site load time - if you do have to use this option then make sure you manually compile the Less into CSS to be included on the production website.
With Sass its a bit more tricky, as you need command line access to your server and privileges to be able to install packages. Instructions on how to go about this can be found on the [Sass website](http://sass-lang.com/install).
The best kind of environment is when your HTML includes the compiled CSS. This way, you can test, commit and deploy your code without having to switch which stylesheet is being used.
## Using a Preprocessor
So your preprocessor of choice is set up and you are raring to get started. So what can you do?
### Nesting
Nesting is a way of grouping styles and classes in your stylesheet, while still keeping it DRY.
The following code probably looks familiar from your raw CSS days:
```css
.article {
padding: 10px;
}
.article h1 {
font-size: 24px;
color: #0046ad;
line-height: 1.4;
}
.article p {
font-size: 14px;
line-height: 1.4;
}
.article .link {
color: #0046ad;
transition: all 0.2s ease;
}
.article .link:hover {
color: #005be0;
}
```
Already, in 18 lines, you are repeating yourself. While you were retyping the 8 characters of `.article` over and over again, I had preprocessed my styles and was already checking twitter on my coffee break.
If we look at how we can improve that CSS using a preprocessor and nesting, we end up with the following:
```scss
.article {
padding: 10px;
h1 {
font-size: 24px;
color: #0046ad;
line-height: 1.4;
}
p {
font-size: 14px;
line-height: 1.4;
}
.link {
color: #0046ad;
transition: all 0.2s ease;
&:hover {
color: #005be0;
}
}
}
```
Immediately you can see that `.article` is only written once. Everything inside the brackets gets compiled to be prepended with that parent. The Sass/Less above would get compiled to the first CSS example.
You might notice the `&` on the link above. That is the parent selector and enables to you extend/modify the parent directly without repeating yourself.
For example:
```scss
.article {
&.wide {
width: 100%;
}
}
```
Will be rendered as:
```css
.article.wide {
width: 100%;
}
```
### Variables
Variables enable to you define constants to be used within your project, so that you don’t have to remember that colour hex, or that sidebar width. Taking our previous CSS from our preprocessor:
```scss
.article {
padding: 10px;
h1 {
font-size: 24px;
color: #0046ad;
line-height: 1.4;
}
p {
font-size: 14px;
line-height: 1.4;
}
.link {
color: #0046ad;
transition: all 0.2s ease;
&:hover {
color: #005be0;
}
}
}
```
The colour `#0046ad` seems to appear a few times. In your project, this might be your brand colour. The line-height also seems to be repeated a few times. In the interest of keeping things DRY, we can use the `$` symbol in Sass (or the `@` symbol in Less) to declare variables. Below is an example of how it might look in Sass:
```scss
$brand: #0046ad;
$line-height: 1.4;
.article {
padding: 10px;
h1 {
font-size: 24px;
color: $brand;
line-height: $line-height;
}
p {
font-size: 14px;
line-height: $line-height;
}
.link {
color: $brand;
transition: all 0.2s ease;
&:hover {
color: lighten($brand, 10%);
}
}
}
```
Declaring the variables first enables us to group the used variables (for easy scanning). It also means that if the brand colour changes, we only need to change it in one place. This above code would still compile to be the same as our very first example - except its a lot easier to read and maintain from a development point of view.
You’ll also notice I've used lighten() on the hover. This is one of the many built in functions available in a preprocessor - meaning that the hover colour will always be a variation of the variable $brand. More about these built in functions can be read in the [Sass](http://sass-lang.com/documentation/Sass/Script/Functions.html) and [Less](http://lesscss.org/functions/) documentation.
### Mixins
The following definition is taken from the [Sass documentation](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#mixins):
Mixins allow you to define styles that can be re-used throughout the stylesheet without needing to resort to non-semantic classes like .float-left.
Similar to a function in programming, they help simplify your styles, saving you from having to remember prefixes or re-writing code. It also allows you to update code in one place, rather than having to find and replace several bits of code.
Heading back to our example code, the transition attributes on the .link class could be consolidated into a mixin. The following syntax is in Sass - [Less mixins](http://lesscss.org/features/#mixins-feature) utilise classes and ids meaning any class can also be a mixin.
```scss
$brand: #0046ad;
$line-height: 1.4;
@mixin transition($attr) {
-webkit-transition:$attr;
-moz-transition: $attr;
-ms-transition: $attr;
-o-transition: $attr;
transition: $attr;
}
.article {
padding: 10px;
h1 {
font-size: 24px;
color: $brand;
line-height: $line-height;
}
p {
font-size: 14px;
line-height: $line-height;
}
.link {
color: $brand;
@include transition(all 0.2s ease);
&:hover {
color: #005be0;
}
}
}
```
Immediately the code is neater and easier to read. The transition mixin can then be utilised throughout the project and if, for example, the `-o-` prefix is no longer needed you only need to remove it from your mixin and the whole project is updated.
### Conventions and Layout
As with any language, defining internal conventions and code layout is paramount. CSS preprocessors have the power to be phenomenal, but they can also be destructive if not maintained and updated correctly.
At Bozboz, the front-end developers have worked hard to define a set of conventions of how files and code should be laid out - for both back and front end.
We also include Luigi in every project. This is our in-house [Sass Library](https://github.com/bozboz/luigi) which contains mixins and functions utilised. This was originally a translation from our Less Library - [Boss](https://github.com/bozboz/boss).
Along with the functionality outlined above, there are plenty of other features in Sass including [File Imports](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#import) and [@extends](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#extend) (these are also available in [Less](http://lesscss.org/features/) if you choose that route). I would advise having a skim over the documentation before embarking on a project with one of them. However, nothing teaches you quicker than getting your hands dirty.
if you’re still unsure about which preprocessor to go for, I wrote about Bozboz moving from [Less to Sass](http://www.mikestreety.co.uk/blog/from-less-to-sass) which might help you sway one way or the other.
Picking up a preprocessor can be tricky, but once you’ve started using one you’ll never go back.
......@@ -2,7 +2,8 @@
title: Bower
date: 2014-05-08
updated: 2016-06-17
intro: Please note: When I have written commands for terminal/command line, I have preceded them with a $. This is not to be typed but signifies a terminal command I have ...
intro: I have recently discovered the power of Bower - a front end package manager. Rather than having to go and find the hosted jquery link, or download the files for fancybox and copy them into my application (website), I can download them off bower.
permalink: "blog/bower/"
tags:
- Web
- Front-end Development
......
......@@ -3,6 +3,7 @@ title: Advanced Gulp File
date: 2014-05-22
updated: 2019-03-27
intro: With gulp starting to find itself into my everyday workflow - I've started to understand its quirks and twists, and how to get along with it. This is an advancement on my original gulpfile from a few months ago
permalink: "blog/advanced-gulp-file/"
tags:
- Web
- Front-end Development
......
......@@ -3,6 +3,7 @@ title: 10 moments I hate about cycling
date: 2014-06-19
updated: 2021-03-11
intro: Evans Cycles blogged "10 Moments Every Cyclist Hates" and before I had even read the blog, plenty of moments popped into my head - these are my top 10
permalink: "blog/10-moments-i-hate-about-cycling/"
tags:
- Thoughts
- Cycling
......
---
title: Building a 3D printer - tips, hints and links
date: 2015-12-10
updated: 2016-04-09
intro: Recently a friend, Chris, and I have embarked on the journey of building our own 3D printer. This is something I hugely recommend if you are into that kind of thing. It's taught me many things already and is amazing to see something moving that you've built.
permalink: "blog/building-a-3d-printer-tips-hints-and-links"
tags:
- Geekery
- 3D Printer
---
Recently a friend, Chris, and I have embarked on the journey of building our own 3D printer. This is something I hugely recommend if you are into that kind of thing. It's taught me many things already and is amazing to see something moving that you've built. I'm in no way a mechanic, so this the kit car equivalent in my world.
This post isn't going to walk you though how to build a 3D printer, but is rather a collection of some tips and tricks we've learnt during the process, along with some links which have helped us understand. Think of it as your friend who has build a printer already, and is just sharing some knowledge to help you out.
The printer we have built/are building is the [RepRap Prusa Mendal - (Iteration 2)](http://reprap.org/wiki/Prusa_Mendel_(iteration_2)).
### Hints
Just some things to note if you are embarking on this journey. If you have something to add, [tweet me](http://www.twitter.com/mikestreety)!
- It takes longer than you think (_a lot_ longer)
- A 3D printer is never finished, it just gets to a state of "being"
- You'll always find something to upgrade - so save your pennies
- Don't be too precious - you'll rebuild every bit of it at some point
- If you have a local hackspace/makerspace (like [Build Brighonton](http://www.buildbrighton.com/)) become a member and go - there will be people to help and tools to use - there is a handy [list of makerspaces](http://www.hackspace.org.uk/wiki/Main_Page)
- No two printers are the same - yours will _look_ like another, but work differently (or you might pick up slightly different parts)
### Links
Many hours of research have led me to this point, you will probably want to do your own research, but these links have helped immensely.
#### Building
For building the printer, these two guides were hugely helpful:
**[The official RepRap guide](http://reprap.org/wiki/Prusa_Mendel_Assembly_(iteration_2))** - Big thanks to Neil Underwood for the videos!
**[Next day RepRap](http://www.nextdayreprap.co.uk/prusa-mendel-build-manual-contents/)** - Despite the name, it's hard to have a RepRap "next day"
......@@ -5,6 +5,7 @@ updated: 2021-03-11
intro: Atom is a fantastic IDE and is hugely powerful. I share my favourite, time-saving tips, packages and shortcuts for GitHub's Atom code editor.
canonical: https://www.sitepoint.com/12-favorite-atom-tips-and-shortcuts-to-improve-your-workflow/
publication: Sitepoint
permalink: "blog/12-favorite-atom-tips-and-shortcuts-to-improve-your-workflow/"
tags:
- Web
- IDE
......
---
title: Building a Vue v2 JS app using Vue-router
date: 2016-11-03
updated: 2019-03-27
intro: Vue JS is a javascript framework which has recently released version 2. Allowing you to display, manipulate and navigate data, Vue is a React, Knockout and Angular competitor. This blog post walks through building a web app with Vue Router.
canonical: https://www.liquidlight.co.uk/blog/building-a-vue-v2-js-app-using-vue-router/
publication: Liquid Light
permalink: "blog/building-a-vue-v2-js-app-using-vue-router/"
tags:
- Web
- Javascript
- Front-end Development
- Vue
---
{% raw %}
At the end of this post, we will have an app which shows a team member list page and team member detail pages, each with their own unique URL
This tutorial uses Vue 2.0.3, Vue Router 2.0.1 and the data has been generated using [JSON Generator](http://www.json-generator.com/). The data set we will be using consists of 7 people with the following attributes:
```js
{
"index": 0,
"guid": "ebee55c4-d685-4d77-a2bb-650283fb8753",
"picture": "http://placehold.it/32x32",
"age": 20,
"eyeColor": "green",
"name": "Hope Dennis",
"company": "ZORK",
"email": "hopedennis@zork.com",
"address": "127 Wortman Avenue, Corriganville, Marshall Islands, 5960",
"about": "Labore velit deserunt sunt labore nisi reprehenderit voluptate consequat laboris id minim. Elit tempor occaecat sunt enim irure aliqua eiusmod minim. Ad culpa laborum laborum anim proident duis ullamco. Sit ipsum id esse proident sunt et dolor excepteur Lorem irure anim. Lorem nisi eiusmod pariatur qui duis sint minim dolore.\r\n"
}
```
The `guid` attribute will be used as the URL
### Loop through data
The first step is to set up our Vue app, looping through the data and outputting the name of each of our users. If you’ve used Vue before, the following should look fairly familiar:
<p data-height="300" data-theme-id="light" data-slug-hash="rrgqmk" data-default-tab="js,result" data-user="liquidlight" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/liquidlight/pen/rrgqmk/">Vue Router - Loop through data</a> by Liquid Light (<a href="http://codepen.io/liquidlight">@liquidlight</a>) on <a href="http://codepen.io">CodePen</a>.</p>
The above code is looping through the data and outputting the `name` attribute for each user. You could chose to output other details such as the email address or company name by inserting `{{ person.email }}` into the HTML code.
### Create the listing component
When using Vue Router, it requires each "page" to be a Vue component. In preparation for this, let’s create a component for the user listing we've just created.
<p data-height="300" data-theme-id="light" data-slug-hash="KgLGqR" data-default-tab="js,result" data-user="liquidlight" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/liquidlight/pen/KgLGqR/">Vue Router - Loop through data</a> by Liquid Light (<a href="http://codepen.io/liquidlight">@liquidlight</a>) on <a href="http://codepen.io">CodePen</a>.</p>
In the example above, I’ve made a template in the HTML using the `<template>` element - this is then referenced from the component using the `id` attribute. I found this was the neatest way of handling multi-line HTML and separating out template code from logic.
In the JS, the component has been called `people-listing` and includes both the template ID and declaring the props for the element. Props allow you to pass data between components - in this instance I am passing the app `people` array into the `people-listing` component. This is done by binding the prop on the HTML element (e.g. `v-bind:people="people"`) and declaring it in the javascript component (e.g. `props: ['people']`) Prop are automatically declared as data, so we can start using it straight away. The component can then called using the new `<people-listing v-bind:people="people" />` HTML tag.
### Create the detail view component
Let’s put aside the listing component and focus on the detail view. In order to display the correct person in our template, we need to select that person from the `data` array and create a component to display the data.
<p data-height="300" data-theme-id="light" data-slug-hash="ALkJoN" data-default-tab="js,result" data-user="liquidlight" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/liquidlight/pen/ALkJoN/">Vue Router - Loop through data</a> by Liquid Light (<a href="http://codepen.io/liquidlight">@liquidlight</a>) on <a href="http://codepen.io">CodePen</a>.</p>
For this example, I’ve hard-coded a `selectedID` variable in the `data` function so we have a GUID (the `guid` variable) to match and select the correct person. Notice I have replaced the `<people-listing />` element in the main app HTML with `<people-detail v-bind:people="people" />`.
To find the correct person associated with the `selectedID` we utilise the `filter` javascript function. This returns an ID, so the first item (`[0]`) is returned. The item is then assigned to the `person` variable and passed through to the component to display it. The HTML then features displays the content required.
### Setup the router
Now we have our two components, we can include Vue Router and start to display different content based on the current URL. To do this, there is some HTML and JS modifications required.
First, include the Vue router javascript file:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.0.1/vue-router.js"></script>
```
The next step is to replace our `people-detail` HTML component tag with one the router understands. Update the HTML view to the following - not forgetting to pass our `people` prop
```html
<div id="app">
<router-view class="view" :people="people"></router-view>
</div>
```
We now need to create a new `VueRouter` instance in the javascript. `VueRouter` accepts several arguments that need to be configured, but i’ll walk you though them:
```js
var router = new VueRouter({
mode: 'hash',
base: window.location.href,
routes: []
});
```
The three options are:
- `mode` - this set’s the navigation mode. The options can be:
- `history` where it users HTML5 History API to simulate different page URLs
- `hash` where it places a hash in the URL before each “page” or
- `abstract` works in all JavaScript environments, e.g. server-side with Node.js
- `base` - The base URL of your script (in this example i’ve used a javascript variable)
- `routes` - this is where we will define each of our routes (URLs or pages)
For this app, I've chosen to use the `hash` mode for navigation. This means we can use the `window.location.href` variable as the base path. If we had use `history` we would need to use a `.htaccess` file or similar to direct all our paths to a single file.
Once set up, `VueRouter` instance needs to be passed into our main `Vue` object:
```js
var app = new Vue({
router: router,
data: {
...
}
}).$mount('#app');
```
Lastly, we need to slightly adjust our components to be objects assigned to a variable, rather than creating HTML elements.
For example, replace the following `Vue.component` call
```js
Vue.component('people-listing', {
```
with a new `Vue.extend` method
```js
var PeopleListing = {
```
We are also going to add a `name` attribute, to make debugging easier
```js
name: 'PeopleListing'
```
Our Vue app should now look like:
<p data-height="300" data-theme-id="light" data-slug-hash="pEmxdk" data-default-tab="js,result" data-user="liquidlight" data-embed-version="2" class="codepen">See the Pen <a href="http://codepen.io/liquidlight/pen/pEmxdk/">Vue Router - Loop through data</a> by Liquid Light (<a href="http://codepen.io/liquidlight">@liquidlight</a>) on <a href="http://codepen.io">CodePen</a>.</p>
Which may seem “broken” as it’s now not outputting any data.
### Create the routes
Routes are the different URLs the app uses to display different components. Each URL needs to be defined in the routes array - including the homepage. The routes we are going to use are as follows:
- `/` - A single slash signifies the homepage of the app, this is going to display our `PeopleListing` component
- `/:id` - The colon signifies the route is variable and will be replaced with the `guid` in our URL - this will display the `PersonDetail` component
Firstly, define the route for the landing page. With this, we are going to define the URL and the Vue component to display when viewing this URL:
If you are the following to your routes array:
```js
routes: [
{path: '/', component: PeopleListing}
]
```
You should see your listing view component appear when viewing the page. This is telling the router to show the `PeopleListing` component when on the `/` path.
Our second route is going to define the person detail view. As we are going to use the GUID dynamically for the URL, we need to name the route. - this will all become clear in a second. Our routes array now looks like:
```js
routes: [
{path: '/', component: PeopleListing},
{name: 'person', path: '/:id', component: PersonDetail}
]
```
The second route now has a `name` of `person` and includes a dynamic variable in the `path`.
Any links using the `router` need to be constructed using the `router-link` element. More details can be found in the [router-link documentation](http://router.vuejs.org/en/essentials/navigation.html).
For example, to link to the landing/homepage you can include the following:
```html
<router-link to="/">Homepage</router-link>
```