http://joewoodward.me/Ghost 0.7Sun, 18 Nov 2018 15:28:23 GMT60I haven't implemented a Caesar Cipher since way back when I started learning C. I remember vividly the excitement of the problem, it was complex enough that it felt daunting but simple enough that I felt like I could tackle it.

I haven't implemented a Caesar Cipher since way back when I started learning C. I remember vividly the excitement of the problem, it was complex enough that it felt daunting but simple enough that I felt like I could tackle it.

"What is a Caesar Cipher?", I hear none of you ask. Well if you are one of the rare few that are interested in code and still don't know, read this

Since I'm now a professional ruby developer I thought I'd give it another go. It's a lot simpler than I remember it!

Great design goes unnoticed, design choices and features that are invisible until analysed i.e. they don't demand your attention.

A great example of this is apple's reversal of the reverse scroll. Remember back when we used to scroll up to move the page down (just trying to remember how it even worked boggles my mind). When apple changed the scroll logic, a lot of people thought it was silly and pointless; they failed to realise that the old method was odd. This small design change made the action so natural to us that we've completely forgotten that it's even happening, now it feels like you are literally touching the digital content and moving it, rather than using a device to manipulate it. IMO we are more connected to our devices now due to this change, the experience is much more immersive.

There are examples of bad design all around us. You don't need to look far to find them. On the flip side, there's a ton of amazing designs around us; however, you need to look with intent to find these, that's what makes them great.

Design is really an act of communication, which means having a deep understanding of the person with whom the designer is communicating

Rule of thumb: if you think something is clever and sophisticated beware-it is probably self-indulgence.

Both of these quotes are very relatable to both industrial design and web-design. Often designers want to add more fancy looks or a font that is over the top. This does not equal great design, it impairs the function of the product.

Vox recently published a video starring Don Norman himself. He explains what inspired him to write The Design of Everyday Things and give an interesting insight into his life.

]]>Syntax highlighting is an amazing tool for really understanding code. Not only does it make it easier to read, it also gives you a second association for the type of object it represents. For example if you read class Foo you know what this means, however if you read

Syntax highlighting is an amazing tool for really understanding code. Not only does it make it easier to read, it also gives you a second association for the type of object it represents. For example if you read class Foo you know what this means, however if you read

class Foo
end

You also have an association with a colour. While there's only one class on display here, consider having multiple code blocks or classes. You can easily pick out the classes just based on colour.

It's actually surprisingly easy with Prism.js. Head over to their site and configure your custom download. I configured mine to highlight ruby, html, css, haml, scss, sass and a few others in the solaris light theme.

Once you have downloaded the files you will receive a .zip file containing a prism.js and a prism.css file.

Once you've got the URL for the latest version, in your Droplet console type cd /var/www/ to change directory to where the Ghost codebase lives.

Next, type wget http://ghost.org/zip/ghost-latest.zip

Remove the old core directory by typing rm -rf ghost/core

Unzip the archive with unzip -uo ghost-latest.zip -d ghost

Make sure all of the files have the right permissions with chown -R ghost:ghost ghost/*

Change into your Ghost directory with cd ghost, then run npm install --production to get any new dependencies

Finally, restart Ghost so that the changes take effect using service ghost restart

From the terminal this seemed to work as expected; however, when I tried to access the site via the browser I was served with a 502 Error from nginx.

First things first, check your error logs for nginx.

Open to /var/log/nginx/error.log and scroll to the bottom of the file, you should one or more errors.

Likely causes

When you updated and ran npm install --production something failed

You forgot to update your nginx configuration to point to the blog

You updated the nginx configuration but not the ghost configuration for your domain name settings

Fixes

First thing to check is that your dependencies have installed correctly during the update.

open the console and cd /var/www/ghost

run npm start --production

watch for dependency errors

You will probably see something like run 'npm install sqlite3 --save' and an error stating that npm couldn't find one or more dependencies. Run the commands as instructed and then try and start npm again, rinse and repeat until you've cleared the dependency errors.

Next check that your nginx configurations are correct. Open /etc/nginx/sites-enabled/ghost and /etc/nginx/sites-available/ghost and check that your server_name is correct. The server_name config will be inside the server block.

server {
server_name joewoodward.me;
}

Last you need to validate your ghost url configuration. Open /var/www/ghost/config.js and look for the production config block. Inside the production block you will see the url attribute, this should match your domain name. e.g.

production: {
url: 'http://joewoodward.me'
}

Once you've validated all of your configs you can restart ghost by running service ghost restart

In my last post I suggested using draper for you decorator needs, I've recently come to believe that advice is only half-right. There's really no valid reason to use draper in most use cases, if you can show me one I'd love to hear it.

What Does Draper Offer That POROs Don't?

IMO, within most generic apps, nothing! You can implement all of the core features of Draper very easily using plain ruby without all of the bloat or context manipulation.

It is a little longer; however, we do not require Draper as a dependency meaning debugging is easier and there is less magic.

Other Issues With Draper

Draper also gently encourages you to make bad decisions. On numerous occasions I've wasted time wondering why @post.published_at or @user.activated_at returns a formatted date or maybe even an html element. It's very easy to overlook the fact that the attribute has been modified in one of your decorators when the object you are working with is named @post or @user.

Draper encourages you to instantiate your objects using their original naming schemes i.e.@book = Book.first.decorate which, not only confuses the namespace; it also makes it difficult to search the codebase for occurrences of the non-decorated vs decorated instances, and makes it impossible to know which object you are looking at when you open a view file without also having to open the controller.

Draper also works some magic to make Rails accept the non-model objects in the forms and links and forces you to delegate calls to the original object for pagination gems such as kaminari. For simple presenter objects, Draper is very bloated, there's really no need for most of these methods in a generic presenter.

How I Create PORO Presenters

In my last example I didn't use the view context, you don't always need to use it; however, many presenters will use the view context to utilize view methods. I like to implement a base_presenter to handle this.

With this implementation we can easily see which object we are referencing in the view without opening the controller file.
We can search the codebase for occurrences of either object.
We don't need to use magic to force Rails to play nicely with modified instances.

What Is The Decorator Pattern?

In object-oriented programming, the decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or

What Is The Decorator Pattern?

In object-oriented programming, the decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.[1] The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.

Issues

It's possible to configure the app to only serve the helpers correlating to the current namespace but we lose the ability to use methods for other classes.

The methods is ambiguous. Consider we create a new model, class Human < ActiveRecord::Base. This will be our avatar in the game. So we need a way to show the health_status for our Humans, but we already have a helper method named health_status. We could refactor the method to return the correct message based on the methods argument class def health_status(object) this would make for a long, messy method. Or we could rename create a new method def human_health_status(human) and rename the zombie helper def zombie_health_status(zombie), this is better but still doesn't fix the fact that all controllers/views can access all of these methods, the larger the application the bigger this issue becomes.

Using Draper to Decorate Our Views

There's a better way to do this, let's use Draper to refactor the zombies helper.