Categories
Coding

3 Easy Steps To Create A Redirect Layout In Hugo

If you’ve created a static site using the wonderful Hugo package and need to create some simple redirect HTML web pages then you’ll need to do the following:

  1. Create your HTML template and place it in your main layout folder.
  2. Create an archetype template file.
  3. Create a file using the archetype and fill in all the meta header information.
  4. Publish your page.

Creating a simple redirect layout in Hugo is relatively easy and can help if you are transitioning from other content providers such as WordPress where your Hugo website structure may slightly change for some posts and pages.

Let’s explore these steps in a little more detail:

1. Create HTML Template

To create a redirecting HTML page we need to create a new HTML file and folder in Hugo.

As we are creating one page to represent one redirect, we will name the file single.html and place it in a new folder which we will label redirect.

When you have done this your folder structure should look something like this:

hugo_root/
  ├── archetypes/
  │   └── default.md
  ├── content/
  │   └── posts/
  │       └── my-blog-posts.md
  ├── layouts/
  │   └── redirect/         <--- CREATE THIS FOLDER
  │       └── single.html    <--- AND CREATE THIS FILE
  ...

Barebones HTML Redirect File

The contents of the newly created single.html file should be as follows:

<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>    
    <meta http-equiv="Refresh" content="0; url='{{ .Params.redirect }}'" />
</head>
<body></body>
</html>

Barebones with Google Analytics

<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>
    {{ template "_internal/google_analytics_async.html" . }}
    <meta http-equiv="Refresh" content="0; url='{{ .Params.redirect }}'" />
</head>
<body></body>
</html>

Barebones with Link in Body

<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>
    {{ template "_internal/google_analytics_async.html" . }}
    <meta http-equiv="Refresh" content="0; url='{{ .Params.redirect }}'" />
</head>
<body>
<!-- uncomment if you want to insert your template's header {{ partial "header.html" }} -->
<p>Please click this [link]({{ .Params.redirect }}) if you are not redirected.</p>
<!-- uncomment if you want to insert your template's footer any {{ partial "footer.html" }} --> 
</body>
</html>

2. Create Archetype Template File

To make it easier for us to remember the content needed in a redirect post we will create an archetype template file with all the needed data.

Therefore, in your archetype folder create a file labelled redirect.md – this must be the same name as the folder created in layouts in the previous step.

Your folder structure for your site should look something like this:

hugo_root/
  ├── archetypes/
  │   ├── redirect.md      <--- CREATE THIS FILE
  │   └── default.md
  ├── content/
  │   └── posts/
  │       └── my-blog-posts.md
  ├── layouts/
  │   └── redirect/         
  │       └── single.html    
  ...

Archetype Template

Then within this file populate the contents like so:

+++
draft = true
date = {{ .Date }}
type = "redirect"
slug = "{{ .Name }}"
redirect = "https://..."
+++
CONTENT NOT RENDERED

Only insert details here if you want to enter any additional detail about the purpose of the redirect, otherwise you can just leave this portion of your file blank. 

There are several important things here to note:

  1. There needs to be a type meta tag which matches the name of the layout folder we just created.
  2. The content are of the markdown post isn’t rendered, therefore you can type whatever you want in here. Maybe even an explanation on what to do in case you forget!
  3. Remember when you’re ready to flick this redirect live change the draft from true to false or remove the draft line completely.

3. Create Redirect Page

To create a redirect page we open up our terminal, in our current Hugo website working directory and enter the command:

$ hugo new redirect/test-my-redirect.md

This should create a new file in your contents folder, such that your directory now looks like this:

hugo_root/
  ├── archetypes/
  │   ├── redirect.md      
  │   └── default.md
  ├── content/
  │   ├── redirect/
  │   │   └── test-my-redirect.md   <--- HELLO WORLD!! =)
  │   └── posts/
  │       └── my-blog-posts.md
  ├── layouts/
  │   └── redirect/         
  │       └── single.html    
  ...

Upon opening this new file you should see something like the following:

+++
draft = true
date = 2020-05-27T16:26:14+10:00
type = "redirects"
slug = "test-my-redirect"
redirect = "https://..."
+++
CONTENT NOT RENDERED

Only insert details here if you want to enter any additional detail about the purpose of the redirect, otherwise you can just leave it blank. 

From here you can edit this file where needed, especially the redirect tag and then remove the draft tag when finished.

4. Publish

Check your redirect file is working first by loading up the hugo local server:

$ hugo server

Test the link by visiting the url: localhost/test-my-redirect

If all works well you should hopefully experience the redirect!

Conclusion

In this article we were able to learn in Hugo:

  1. How to create a custom template layout.
  2. How to create an archetype to help use the layout needed for this type of layout template.
  3. How to create a new page using the archetype and its corresponding layout.
  4. How to publish our new layout and test.

Hopefully your redirect issues in Hugo will be solved with this helpful post.

Categories
Coding

Best Way to Install NodeJS on Mac OS

Once every year I make it a priority to nuke my Macbook Pro computer.

There are two reasons why I do this is to keep the apps I actually use, naturally removing the ones I no longer use, but don’t know that I no longer use them!

As I like to try new things it does mean I install lots of scripts and apps on my computer and because I might not actively remove these things from my computer when I no longer need them my computer gets bloated.

By nuking your computer frequently it helps to completely remove unused and unnecessary scripts and apps from your machine.

Keep essential files backed up in the cloud

Knowing that I nuke my computer annually it helps to be more mindful of placing essential files on the cloud. There may come a day where my computer decides it doesn’t want a human to initiate the nuke, it wants to do it itself! When that happens all essential files still stored on my computer maybe lost forever.

This then has helped to structure my thinking into what to do with files as I am working on them. For example, if I’m writing a blog post I ensure I’ve already sent it to my private BitBucket repository, or if I’m working on a spreadsheet I store this in Google Drive or OneDrive.

It’s important then to make sure you are aware of the type of document you are handling and how this can be backed up if you’d like to keep it.

Moving on to our topic today, even though I nuked my computer 1 month ago, I’ve realised today I need to install NodeJS.

The problem I have with NodeJS is having it automatically update itself. I don’t want to have to re-install the direct downloadable file from NodeJS every time there’s a patch update.

Wouldn’t it be great to install it once, and when needed, run a command for it to automatically update?

Thankfully there is such an easy process: Homebrew for Mac

So here were the steps I undertook to be able to reinstall NodeJS back on to my computer:

Check if NodeJS is already installed:

Before you install node you may want to check if you already have it installed. To check if node is already on my machine run node -v in your terminal. This simple command checks the version number of the currently installed node module on your computer.

$ node -v
bash: node: command not found

If you have node installed, you should see a version number pop up underneath your command. Great, there’s nothing more for you to do here! If though, you see the above, move on to the next step.

Do some Homebrew housekeeping first

Before installing node, let’s do a little housekeeping to make sure our computer is updated and everything is in working order.

a) Check your system has the latest updates by running the command brew update:

$ brew update
Already up-to-date

If you see Already up-to-date then you’ve got the latest updates on your machine. If not, you would have noticed a bunch of modules updated on your system.

b) Check your system is humming along well with no conflicts by running brew doctor:

$ brew doctor
Your system is ready to brew.

If you see Your system is ready to brew then your computer is ready to proceed. If not, please read through any of the instructions provided on how you can correct your modules.

Install NodeJS using Homebrew

Our final step then is to simply run the command brew install node:

$ brew install node

You should see lots of action, and to check you’ve properly installed it, re-run our first command in terminal node -v:

$ node -v
v14.2.0

Now you’re ready to use NodeJS.

Categories
Coding

How To Easily Install Bootstrap (2.0) in ExpressJS (3.0)

I’m certainly no expert when it comes to using ExpressJS or Bootstrap so there may be far better ways of doing this than what I detail below, however, if you do know of better ways please let me know as I bumbled my way through!

Here goes.

Prerequisites:

I’m installing this on an Ubuntu 11.10 EC2 micro box and have the following installed:

$ apt-get install node npm make zip unzip git

Process:

  1. Install via NPM the following: ExpressJS, Less & [UglifyJS]():
$ npm install -g express less uglify-js
  1. Create an ExpressJS working directory, we’ll call it testme, with Less:
$ express --css less testme
  1. Move inside your new directory:
$ cd testme
  1. Create a new directory called vendors:
~/testme$ mkdir vendors
  1. Move inside the vendors directory:
~/testme$ cd vendors
  1. Download from github Bootstrap:
~/testme/vendors$ git clone https://github.com/twitter/bootstrap.git bootstrap
  1. Move into the newly created Bootstrap directory:
~/testme/vendors$ cd bootstrap
  1. Build Bootstrap:
~/testme/vendors/bootstrap$ make -i 

You may see a cannot remove docs/assets/bootstrap.zip file – just ignore. It would also be great if you could make to a target directory, but I couldn’t find how this could be done.

  1. Once the build has been completed, move to the docs/assets directory:
~/testme/vendors$ cd bootstrap/docs/assets
  1. You should see a css, img, js folders and a bootstrap.zip file:
~/testme/vendors/bootstrap/docs/assets$ ls
  1. Go back to the testme folder:
~/testme/vendors/bootstrap/docs/assets$ cd ~/testme
  1. Move the bootstrap zip file you just created into your public folder:
~/testme$ mv vendors/bootstrap/docs/assets/bootstrap.zip public
  1. Move to the public folder:
~/testme$ cd public
  1. Unzip the bootstrap.zip file:
~/testme/public$ unzip bootstrap.zip
  1. You should see a bootstrap folder in the public folder
~/testme/public$ ls
  1. Remove the bootstrap.zip file:
$ rm bootstrap.zip
  1. Now it’s a matter of linking to the bootstrap stylesheets in your jade layout template files. Edit the views/layout.jade file to include references to the bootstrap files, remember Bootstrap needs the latest jQuery, so you may want to include reference to this too, here’s what my layout.jade looks like:
!!!
html
head
title= title
link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css')
link(rel='stylesheet', href='/bootstrap/css/bootstrap-responsive.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js')
script(src='/bootstrap/js/bootstrap.min.js')
body
block content
view raw layout.jade hosted with ❤ by GitHub

2. To test that it works, edit the views/index.jade file to include a reference that Bootstrap will be able to use, something like:

extends layout
block content
div.top
form.form-horizontal(method="post", id="loginForm")
label Username
input.span3(id="username", type="text", name="User", placeholder="Enter your username")
label Password
input.span3(id="password", type="password", name="Password")
input.btn(type="submit", value="Log In")
div.container
div.content
table.table.table-striped
thead
tr
th Table
th Heading
tbody
tr
td Blah
td Test
tr
td Hello
td World
div.footer
p © 2012 All rights reserved.
view raw index.jade hosted with ❤ by GitHub

There you have it!

Being able to use a compiled Bootstrap file with your ExpressJS install.

Categories
Coding

Common Mistakes With Jekyll Front Matter

As I don’t blog very often whenever I create a new blog post in GitHub Pages (using Jekyll’s template framework) there a couple of times I forget the basics and spend a few minutes trying to figure out why the page didn’t load properly.

So this post today is more of a note to self.

Firstly, for blog posts name the file according to the following convention:

YYYY-MM-DD-BlahBlah.md

Secondly, in the front matter area don’t use another colon in the value of the variable. For example don’t do this:

title: Errors: Why do they happen?

Just use another type of punctuation, like:

title: Errors - Why do they happen?

Lastly, every variable in the front matter must contain a name followed by the colon. You cannot create a one-liner variable like this:

redirect_from "yoo/hoo/im-here"

Must be in this type of format in the case of redirect_from:

redirect_from: - yoo/hoo/im-here

Anyway, these are the pesky little bugs that trip me up all the time and tend to cost me a few minutes to an hour of scratching my head trying to figure out what on earth is happening. Hopefully by documenting them I can squash them quicker!

Categories
Cloud Apps Coding

How To Print More Than 1 Page In Advanced PDF/HTML Templates

I like NetSuite’s Advanced PDF/HTML templating system with the FreeMarker syntax. However, there are a couple of issues I’ve run into and one just recently:

How can you force printing on two or more pages?

One example I’ve been working on is the ability to print “how to pay” information on the back of our invoices that are issued to our customers.

As our invoices can span a few lines we have been squeezing that information down in the footer of the page. This makes for small font and errors from the customer when entering payment details. I mean, you’ve got a lot more space on the back than you do in the footer! It would be so much more convenient if this information were to be printed on the back of the invoice, but to do this it would mean getting the template to do a page break.

After asking for this feature request to NetSuite some time ago, I came across an interesting, and simple, CSS technique that actually works!

The solution?

  1. Just measure the dimensions of the paper you would like to print. Or obtain standard paper dimensions from the web.
  2. Enter this information into a CSS class in the <style> area within your PDF/HTML template.
  3. Reference this class whenever you want to do a page break.

Here’s a simplified template demonstrating this concept:

<?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
    <head>
        <macrolist>
            <macro id="nlfooter">
                <table>
                    <tr>
                        <td>This is the footer. I've chosen to span this over each page.</td>
                    </tr>
                </table>
            </macro>
        </macrolist>
        <style>
            /* Insert the physical dimensions of the size of the paper you print.*/
            /* Width = page width; Min-height = page height; */
            /* (You may/may not need to have `margin-right:1.5cm`. I found the contents spilled off the page without it.)*/
            .page { margin-right: 1.5cm; width: 21cm; min-height: 29.7cm; }
        </style>
    </head>
    <body footer="nlfooter" footer-height="15%">
    <div class="page">
        <h1>Welcome to the first page!</h1>
        <p>Place all your first page information here. For example, you may want to put your company logo, the invoice date, number, contact address of the customer, and then you'll want to loop through all the items in the invoice in a nice neat table.</p>
        <p><strong>Notice how the right-margin is a little funny?</strong></p>
        <p>You may need to increase the `margin-right` value on the `page` class attribute to make this margin look nicer on the page. Play with it.</p>           
    </div>
    <div class="page">
        <h1>Welcome to page 2!</h1>
        <p>You should now see this on the second page.</p>
        <p>This is where you can place additional information on whatever else is important, i.e. how to pay, etc.</p>
    </div>
    </body>
</pdf>

As you can see from the comments, all you need do is enter the dimensions of the size of the paper into the .page attribute and then reference that class whenever you want to apply a page break.

How did that demo turn out?

Have a look at the demo copy of the PDF and see for yourself.

Nice!

Categories
Coding

Function That Receives An Array Of Strings & Outputs Most Used String

I love the occasional programming challenge and yesterday I came across the following:

Create a function that receives an array of strings and outputs the most used string?

I pondered on this for awhile and in my mind thought of the following process:

  1. Loop through each element of the original array;
  2. Count the occurrences of each element by looping through the array again;
  3. Sort the new array;
  4. Output the new array’s first element.

However, looking at this I realised I was looping way too many times!

So I refactored my code such that it does the following:

function getModal( arr ) {
  var maxCount = 0;
  var result = "";
  arr.reduce( function( p, el ) {
    p[el] ? p[el] += 1 : p[el] = 1;
    if ( p[el] > maxCount ) {
      maxCount = p[el];
      result = el;
    } 
    return p;
  }, {} );
  return result;
}

var e = ["h","g","x", "d", "b", "h", "x", "i", "s", "g", "x", "p"];

console.log( getModal( e ) ); // => "x"

Notice how there’s only one looping array function used – reduce.

What this function does is take the array arr as a parameter, create two variables to measure the maxCount and another to take the result. As we then loop through the arr we assign each element (being a string) as a key to the new object created by reduce and make it’s property value equal to the count.

This makes counting the number of occurrences relatively easy.

All we then do is check whether the property value is greater than the maxCount value and if it is to make that value equal to the maxCount and the result equal to that element.

Once we’ve finished looping through the arr we then just simply output the result.

If we need to output the count of occurrences we could just change our code to output:

return {
    answer : result,
    count : maxCount
};

Anyway, I’m sure there is a better answer to my response, but I liked the challenge and I also liked the refactoring process – looking at my code and finding a better way.

Categories
Cloud Apps Coding

How To Assign A Blank Cell To A Default Value

Perhaps the easiest way to assign a default value to a variable is to append the || conditional after referencing the variable.

For example, after looping through an array and mapping the values to properties within an object, I needed to test whether the property had been assigned.

As I use Google Spreadsheets to iterate through data imagine the following data set:

ABC
1NameAgeChoice
2Ryan50A
3Sara27
4Jude29C
Data set containing rows of data, except for one row with a blank “Choice” value.

Upon grabbing this data in Google App Script using a quick one liner:

var data = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); 
// => [[ "Name", "Age", "Choice" ], [ "Ryan", 50, "A" ], [ "Sara", 27,  ], [ "Jude", 29, "C" ]]

We now have our sheet data wrapped into a 2-dimensional array.

If we now reduce this array into an object such that we can easily reference each element within the data variable we should easily be able to do like:

var obj = data.reduce( function( prev, el, i ) {
    var result = {};
    if ( i > 0 ) {
        result.name = el[0];
        result.age = el[1];
        result.choice = el[2];
        prev.push( result );
    }
    return prev;
}, [] );

Hopefully the above code is somewhat self-explanatory, but here we only have one condition and that is to remove our header row in our data and then mapped all elements within our array to a property – in essence corresponding to the header titles.

However, upon doing our data manipulation we’d now like to return it back to the sheet and therefore need to map it back to a 2-dimensional array. Here’s how that code would look:

var arr2d = obj.map( function( el ) {
    return [ el.name, el.age, el.choice ];
});

This may appear to look great, but if we were to inspect the arr2d variable we would find it showing this:

// => [["Ryan", 50, "A"], ["Sara", 27, undefined], ["Jude", 29, "C"]]

Most of that is fine except for the ugly undefined. Ugh! If we were to return this back to the sheet we would get the undefined word populating our sheet.

So what can we do?

There are a couple of things, but one such simple way is to apply the || conditional on that final map method, making it look like this:

var arr2d = obj.map( function( el ) {
  return [ el.name || "", el.age || "", el.choice || "" ];
});

// => [["Ryan", 50, "A"], ["Sara", 27, ""], ["Jude", 29, "C"]]

Now the result is looking much neater and we can return the results as is back to the sheet.

Anyway, be mindful of undefined when working with arrays and objects when sucking data out from Google Spreadsheets playing with it and then returning it back to the sheet. It could make for an unsightly sheet!

Categories
Coding

Function Hoisting In JavaScript

When writing functions in Javascript it can be a little confusing. Hopefully by walking through a few examples we can see the nature of hoisting in Javascript to better understand it’s behaviour.

In Javascript the following functions are hoisted:

function foo() {
    function bar() { return 1; }
    return bar();
    function bar() { return 2; }
}
console.log( foo() ); // => 2 

Notice how within the foo() function that there’s a return statement between the two bar() functions. Surely the second bar() function would never run, however, as our console.log reports it indeed does!

Why?

The reason for this is that the functions are hoisted within foo() one after the other and then the return statement is placed underneath. It would be equivalent to writing:

function foo() {
    function bar() { return 1; }
    function bar() { return 2; }
    return bar();
}
console.log( foo() ); // => 2

What happens if we tried the following – we create a bar variable and call an anonymous function?

Like so:

function foo() {
    var bar = function() { return 1; };
    return bar();
    var bar = function() { return 2; };
}
console.log( foo() ); // => 1 

Why do we get 1 in this result?

Here the functions aren’t hoisted and instead the way the function operates is as follows:

function foo() {
    var bar = undefined; // first bar declared
    var bar = undefined; // second bar declared
    bar = function() { return 1; };
    return bar();
    bar = function() { return 2; }; // this never gets parsed as we’ve hit the return statement above
}

Now we never get to that second function due to the return statement.

Categories
Coding

How To Flatten An Array Of Arrays

There can be times when working with arrays that you need to be able to turn the array into one dimension. For example, you may have a situation whereby you have the following array:

[ [ 1, 2 ], [ 3, 4, 5 ], [ 6 ], [ 7, 8 ], [ 9 ] ]

And you just want to be able to transform that array such that it is magically turned into something like this:

[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

So how do we do this in Javascript?

Well, thankfully there’s an easy way! And the reduce function can help to flatten 2d arrays.

Here’s what the reduce function looks like with it’s arguments and parameters:

Array.prototype.reduce( function( previousValue, element, index, array ) { 
    //...
}, initialValue ); 

So, given the following array:

var arr = [ [ "a", "b" ], [ "c" ], [ "d", "e" ] ];

var flat = arr.reduce( function( a, b ) {
    return a.concat( b );
});

console.log( flat ); // => [ "a", "b", "c", "d", "e" ]

What this reduce function does is take a previousValue parameter as the first parameter then a currentValue as the second parameter and whatever is returned from this function is what is inserted into the previousValue parameter.

Therefore if we were looking at this example at each iteration it would look as follows:

passpreviousValueelementindexarrayreturn
first pass0[ “a”, “b” ]0arr[ “a”, “b” ]
second pass[ “a”, “b” ][ “c” ]1arr[ “a”, “b”, “c” ]
third pass[ “a”, “b”, “c” ][ “d”, “e” ]2arr[“a”, “b”, “c”, “d”, “e” ]

However, in the following example note what happens when the first element in the 2-dimensional array is NOT an array:

var arr = [ "a", [ "c" ], [ "d", "e" ] ];

var flat = arr.reduce( function( a, b ) {
    return a.concat( b );
});

console.log( flat ); // =>"acd,e"

Here, we need to be mindful that because the FIRST item in this array is NOT an array itself it will cause the remainder of the elements within the array to be concatenated as a sting.

Therefore, to get around this we should take advantage of the optional initialValue parameter after the callback function and we would therefore modify our code as follows:

var arr = [ "a", [ "c" ], [ "d", "e" ] ];

var flat = arr.reduce( function( a, b ) {
    return a.concat( b );
}, [] ); // <= note what happens here!

console.log( flat ); // => [ "a", "c", "d", "e" ]

We could have similarly used the same initialValue in our first example and this would have given us the same result.

This certainly comes in handy when working with Google Spreadsheets!

Categories
Coding

What Are The JavaScript Equivalents Of “AND” And “OR”?

In Javascript we use the && (double ampersand) and || (double pipes) to denote and and or respectively. Think of it is a symbolic representation of the English words.

However, we can use both of these symbols to determine if something is truthy. This can also help with variable assignment if we’re relying upon other variables having values.

Let’s see if you can follow the logic with these examples.

If you are testing whether a variable is truthy and want to return another truthy value you can do the following:

var e = “test”;
var f = 2;
console.log( e && f ); // as both variables are true returns the last variable `f` being 2.

If we changed the value of e to a falsey value such as false, null, or 0, we get…

var e = null;
var f = 2;
console.log( e && f ); // => null

If we switch it, such that f is a falsey value we get…

var e = 2;
var f = 0;
console.log( e && f ); // => 0

So in both of the previous two cases the falsey value gets returned.

What happens then if we replace the && with ||, here are our results:

var e = "test";
var f = 2;
console.log( e || f ); // => "test"

Notice how we get the first truthy value.

var e = null;
var f = 2;
console.log( e || f ); // => 2

And again we get the first truthy value being the variable f.

So what would you expect if we now started combining these expressions?

var e = null;
var f = 2;
console.log( e && f || 1 ); => 1

Why?

As the ( e && f ) expression returns the first falsey value, being null it’s then used in the second comparative statement null || 1 and we know that with || comparisons it returns the first truthy value being 1 (as null is falsey).

Cool.