What Is Clocks?

I've recently started working on a project that's much bigger than anything I've made before and involves a whole host of new things I know nothing about. We've got API calls, database creation, AJAX requests, form handling, and much more. I'll talk about what the project actually is in a later post, but for now I wanted to write about how I'm using grunt to automate my workflow. Also, I wanted to type 'automate my workflow' because it makes me feel like a legit developer. As usual with my posts, this topic is not exactly revolutionary to the wider dev world. It is, however, revolutionary to me. A couple of weeks after publishing my Ghost theme, another github user raised an issue with this picture of Scrawl being viewed on Safari: Uggh. Safari. There ended up being a couple of completely unrelated css properties that Safari took issue with, which took some fiddling and a who load of vendor prefixes to fix. So, that added auto-prefixes to my admittedly short workflow of 1. start server and 2. sass watch. I'm easily overwhelmed and very forgetful though, so my husband suggested using grunt when I began working on my new project. So, what is grunt? It's a build tool, which in essence means that it manages and co-ordinates scripts that automate development tasks and/or prepare your project for deployment. The core Grunt package comes with the functionality to create 'tasks', references to a script and set of options, and then assign these to commands that can be run in the terminal. As a user, you can write scripts yourself, or import one of the many Grunt plugins and use scripts from that. I have two commands set up: 'default', which watches my sass folder for changes, compiles them in to css and then runs an autoprefixer over the css to add vendor prefixes; and 'server' which starts up my express app, watches all of my template and js files for changes and restarts the server when any are detected. Here's the code for the 'server' profile: //importing the express plugin grunt.loadNpmTasks('grunt-express-server'); //importing watch plugin grunt.loadNpmTasks('grunt-contrib-watch'); //all grunt configurations must be wrapped by this function grunt.initConfig({ //express task with one profile that runs main.js (i.e. starts up my server) express: { dev: { options: { script: 'server/main.js' } } }, //Watch is a plugin that allows you to monitor a set of files for changes, and then trigger scripts or other tasks. My express profile watches all of my templates and js files and then runs express:dev defined above. 'atBegin: true' means that the task passed to this profile will be ran once when it is first called, before beginning to watch. watch: { express: { files: ['client/templates/**/**.njk','server/**/**.js' ], tasks: [ 'express:dev' ], options: { atBegin: true, spawn: false } } //assigns the command 'server' to the express profile of the watch task. grunt.registerTask('server', ['watch:express']); } As you'll see, all of these configurations are defined within a javascript object, which is passed to the initConfig method. It can look a little intimidating at first because this object can get pretty huge. When you work through it line by line, though, I think it's pretty easy to use.

Learning to use Grunt to automate tasks

I've recently started working on a project that's much bigger than anything I've made before and involves a whole host of new things I know nothing about. We've got API calls, database creation, AJAX requests, form handling, and much more. I'll talk about what the project actually is in a
I decided to have a stab at using the Twitter API, pretty much to see what it's like. Not wanting to sink too much time into anything complex, I settled on making a simple script that published a tweet to my channel, and which could be ran from the command line. To ritz it up a little I decided that, depending on the "radness" of the tweet, it should append #thatsRad or #thatsNotRad. It only took 30 mins to throw together and was pretty satisfying to make. Although I barely grazed the surface of what Twitter's API can do, it still makes it a little less daunting to have actually used it. On to the code: function isItRad (tweet, radness) { var Twitter = require('twitter'); //Creating new Twitter client instance, which is a class provided by the npm twitter module. var client = new Twitter({ consumer_key: "KEY", consumer_secret: "KEY", access_token_key: "KEY", access_token_secret: "KEY", }); var tag; // Checking the second argument passed to function, and assigning appropriate hashtag to 'tag' variable if (radness === "rad") { tag = "#thatsRad"; } else if (radness === "notRad") { tag = "#thatsNotRad"; } else { return console.log("you have not entered a radness level."); } //Making sure the tweet is the correct length if (tweet.length > 140) { return console.log("your tweet is too long at " + tweet.length + " characters"); } else if ((tweet.length + tag.length)>140) { client.post("statuses/update", {status: tweet}, function(error, tweet) { if (!!error) { console.log(error); } else { console.log("your tweet has been published, but without radness because it was too long"); } }); } //using POST method to push tweet to my "statuses" feed. There are other types of POST methods for updating favourites etc. else { client.post("statuses/update", {status: tweet + " " + tag}, function(error, tweet) { if (!!error) { console.log(error); } else { console.log("your tweet has been published!"); } }); } } //this assigns the arguments passed to the script via the command line to variables. This is for tidiness more than anything. var tweet = process.argv[2]; var radness = process.argv[3]; isItRad(tweet, radness); So what did I learn? This was a simple script, and my learning outcomes were simple to match. Processing command line arguments: Pretty self explanatory, you can see how it's done above. Some fundamentals of authentication: Whilst I didn't do much in terms of authentication, the reading I did around using consumer keys and access tokens (which are included in all requests an app makes to the twitter API for validation) helped me to understand a little about how oAuth works. Callback functions: Lets ignore that fact that my script had nothing else to be getting on with whilst waiting for the API to respond. Still, it's useful to get the feel for the syntax of asynchronous functions, even if they're actually executing synchronously. Using APIs is easy: At least if it's a well maintained one, and you're writing a single function.... In summary, this script did it's job of making APIs, node, and async programming that much less intimidating.

Is it rad? A simple script using the Twitter API

I decided to have a stab at using the Twitter API, pretty much to see what it's like. Not wanting to sink too much time into anything complex, I settled on making a simple script that published a tweet to my channel, and which could be ran from the command
If you take a look at the code for the Scrawl Ghost theme that this site uses, you'll notice that it's pretty compartmentalised. I hesitate to use the word modular, as I didn't really write it with swapping elements in and out in mind. My reason for having one million handlebar partials and mirroring those will one million Sass partials is a simple one: it allows me to more easily keep a map of my code in my head. I'm not sure if this is because I'm a beginner, or just how my brain works, but the more broken down the code I write is (on any project), the less messy my thought process is in relation to it. I decided to have a go at writing Tumblr themes, for no other reason than I'd already made a couple of Ghost themes (now including the site for Indie Games Studio press1 Games) and wanted to make something similar but different. However, after some brief research I discovered the following: There's no local dev version of Tumblr you can download to work on and test out your themes. Tumblr themes have to be one huge, ugly HTML file.** The former is pretty annoying, especially because I'm currently travelling and have no guarantee of a stable internet connection. Even with a stable connection, having to copy and paste my code into the tumblr interface and add in my asset file each time I make a change is somewhat bonkers. I'm not sure what the justification is, but I'll get over it I guess. The latter point makes sense given the overall aesthetic and use of Tumblr: most blogs I follow on Tubmlr have a main page that displays all of their posts, and very little else. Having one HTML file for the whole site nudges you in this direction, as things get messy when you start trying to do more complex things with pages that aren't the post index. However, as I've mentioned above my brain seems to fail in a linear proportion to the number of lines of code each of my files has. So, in order to make a Tumblr theme without going bonkers, I decided to compartmentalise my code using Nunjucks, and then precompile it into one file that I could paste into the Tumblr interface. This turned out to be pretty easy, actually. Here's the code: var nunjucks = require("nunjucks"); var path = require("path"); var fs = require("fs"); nunjucks.configure(__dirname, { autoescape: true }); function compile() { var source = "source.html"; var destination = "main.html"; fs.writeFileSync(destination, nunjucks.render(source)); } compile(); Voila! For now, I just run this script in my terminal whenever I want to compile, but I'll turn it into a grunt watch script so that it compiles on the fly whenever I make changes to source.html. Above, I mentioned that modular probably isn't the right word for my Ghost theme(s), because I didn't really try to write them with the potential for switching out elements in mind. However, I want to write a few paid-for Tumblr themes and so modularisation seems like a good approach to prevent me from re-writing similar code for each theme. At the moment I have the following structure for my .njk template files and my .scss file: head.njk/.scss pages.njk/.scss index.njk/.scss foot.njk/.scss post_types/ answer_posts.njk/.scss audio_posts.njk/.scss chat_posts.njk/.scss link_posts.njk/.scss etc, etc. This way, I can easily find and tweak the look of specific post types, or the overall layout and structure. So, watch this space :) **Well, you can have additional asset files for css and whatnot

Breaking down your Tumblr theme

If you take a look at the code for the Scrawl Ghost theme that this site uses, you'll notice that it's pretty compartmentalised. I hesitate to use the word modular, as I didn't really write it with swapping elements in and out in mind. My reason for having one million
One of the best things about Ghost is that it's admin interface is simple and very content focused. The downside of this when making a sharable theme is that it doesn't offer much in the way of configuration options to the user. Whilst there are some fields to enter the blog title, logo, etc. there's currently no way to add configuration options to the admin settings interface. Annoying, because when building Scrawl I wanted to have a row of social buttons in the footer of the page linking out to the user's profiles. When facing this common problem generally theme writers either charge for extra configuration, or (with free themes) tell the user where social buttons are defined in the code so that they can change the url values themselves. Not so great if a non-technical user wants to use your theme. Or anyone, really, who just wants to press a button and have a theme please. The ghost admin interface does contain two code injection boxes, the input to which will be injected into either the header or the footer of the blog, depending on the which box is used. This is where the Ghost Theme Configuration Approach comes in handy! Using this approach was a really valuable learning tool for me, as it's given me experience implementing a solution that I wouldn't have come up with myself, but had to understand to use properly. It essentially works by defining an object, which should always be called window.__themeCfg to allow for cross theme compatibility, and then allowing the user to define properties for each of the social media platforms they want buttons for/ your Ghost theme supports. My installation instructions say: The configuration for Scrawl uses the code injection interface, which you will find at yourwebsite.address/ghost. Each social network or profile that you want to add requires only one line adding to the blog header code injection. Below is the list of the social media platforms currently supported. Choose the ones that you would like to include on your blog and copy the code. Then, replace the ... with your username for that platform. Remember to keep the speech marks! For example, if I wanted to add a link to my twitter profile to a blog using Scrawl I would simply put <script>window.__themeCfg.twitterUsername = 'ktweeden';<script> I then list the scripts that they can paste in, for example: github: <script>window.__themeCfg.githubUsername = '...';<script> The script that runs over these looks like this: function revealPlatform (platform) { /** Takes platform argument and creates variable that matches the ___themeCfg property pattern **/ var reference = platform.toLowerCase()+"Username"; /** Checks if property exists (i.e. if user has assigned it to their username) **/ if (window.__themeCfg[reference]) { /** All buttons exist in HTML but have display:none. This removes that styling to reveal relevant button. **/ $(".social-button."+platform.toLowerCase()).removeClass("hidden"); /** forms URL to user profile using URL pattern defined in formSocialUrl() elsewhere **/ $('.social-button.' + platform.toLowerCase()).attr('href', formSocialUrl(platform, window.__themeCfg[reference])); } /** Prints config instructions to console if not configured **/ else console.warn("To add a " + platform + " profile link to your blog, put '\x3Cscript\>window.__themeCfg." + reference + "= \'my" + platform + "Username\';\x3C/script\>' in the Ghost code injection!"); } //runs above on each available social network function revealSocialLinks() { revealPlatform('Twitter'); revealPlatform('Github'); revealPlatform('Facebook'); revealPlatform('Instagram'); revealPlatform('Tumblr'); revealPlatform('Pinterest'); revealPlatform('Bitbucket'); revealPlatform('Codepen'); revealPlatform('Youtube'); revealPlatform('Vine'); } //runs on DOM ready $(revealSocialLinks); The downside to this is approach is that __themeCfg is a global variable. Ghost requires themes to include the {{ghost_head}} and {{ghost_foot}} helpers, which contain...some mystery code of mysteries (or, SEO stuff). We don't know that they haven't got a variable with the same name. However, the people at Ghost do know about this configuration approach and seem to like it, so I'm assuming they would have said if there was a conflict... Anyway, it seems like the least worst solution for now.

Making my ghost theme configurable

One of the best things about Ghost is that it's admin interface is simple and very content focused. The downside of this when making a sharable theme is that it doesn't offer much in the way of configuration options to the user. Whilst there are some fields to enter the
So I've made a basic front end, now I want to have a bit of a go at making a backend. I think for some a better learning approach might be to double down on the frontend and embed that knowledge a little further. However, I'd rather have a low level of understanding about the whole shebang from which to grow. I don't like blindly giving commands to Ghost, for example, that does something useful without a clue of how it works. Initially, I wanted to learn more about backend development by making a small app/website but as I started to think about what my learning goals for that would be, and consequently what the project might be I quickly realised that my knowledge and understanding of this area is so low that there's some basic learning I need to do before I get making. Project: What is servers? Learning goals Node and npm: Although I've typed "npm start" into my console a fair few times now to start a Ghost production server on my laptop, I'm not exactly sure how this happens. In order to feel a bit more confident trying out some full stack development I want to understand the basics of why and how node is used, and what node package manager does. Networking:I want to understand the fundamentals of networking, by which I essentially mean, what actually happens when you type "google.com" into your browser. I'm currently spending a month in China, so when I type google.com into my bowser the Great Firewall of China sends a giant nope right back. I'll get around to looking into that after I understand a bit more about what's supposed to happen! Approach I'll be "weibo-ing" it. Jokes, I'll be googling using a vpn.

What is servers?

So I've made a basic front end, now I want to have a bit of a go at making a backend. I think for some a better learning approach might be to double down on the frontend and embed that knowledge a little further. However, I'd rather have a low