Saying Goodbye to WordPress

I have been using WordPress for a while with my personal blog, JPtacek.com. I have been a big fan and have written up many posts about setting up WordPress using the awesomeness of Azure websites. However, the time to move on has come upon to a new blogging platform. Sylvester ByeBye WordPress logo So the question is why... Well here is my reasoning

  • A CMS does a great many things, but ultimately they are for people to be able to host websites and publish content. And most CMSes are for people who do not want to learn about things like HTML. However, with a developer background I kept running into things I could easily do in HTML, but were near impossible within WordPress
  • Azure is great, however I still pay for Azure. I am responsible for CPU and bandwidth. Since WordPress is a platform, every page requests is essentially run through a CPU, where the WordPress blackbox does its magic, queries a database and spits out HTML. This is a cost. (To be honest, it is not a BIG cost)
  • It always felt a bit goofy to have simple web pages hosted in a back end database. Everything starts as a document or HTML, then gets thrown into a database. I need to be responsible for backing up the database and being a good admin type person. I would rather just have my one true source be HTML that I can save in Dropbox or SkyDrive
  • PHP is not my thing. I am always up for learning something new, but PHP is NOT something I that is on the learn something new list.
  • Update, update, update. Since WordPress is a platform, hackers tend to get bored and are always looking to hack into it. You constantly need to be aware of keeping your software and plugins up to date if you are hosting your own WordPress environment. This is not an issue if you are hosting at WordPress.com, but I am not, on account of the awesomeness of Azure Websites
  • Truthfully, probably the biggest reason is JavaScript. Doing web front end things with WordPress is really not a pleasant experience. I have found myself resorting to embedding JSFiddles into my pages to show functionality that is plain easy to do on other platforms.

So what am I looking for?

  • More web, please. I want to be able to have a blog engine that supports HTML and JavaScript, rather than make me miserable
  • Speedy please
  • Reduce hosting costs, please
  • Help me learn something new, please

I have been spending time thinking about this. I believe I have an answer. Any suggestions from you oh mighty Internet?


 

Calculating the Cost of the 12 Days of Christmas

Every year in December, families gather around the table to celebrate Christmas. If your house is anything like my house, the good times, food and conversation can quickly escalate into a battle over what is the true cost of the classic Christmas Song, the 12 Days of Christmas! This year, I took matters into my own hand and wrote a calculator, that will calculate the cost of the 12 days of Christmas using Google's Javascript Framework, AngularJS. No more bickering at the family table over the holidays!

AngularJS is a Javascript framework from Google that focuses on building complex data applications. It has a very strong data first philosophy, which is a little different than jQuery which focuses more on DOM manipulation. You can find out more about AngularJS at the official site, or read some recent blog posts I have written up at http://www.jptacek.com/tags/angularjs/.

AngularJS is a Model View Controller (MVC) framework. The model represents our data, or an object. In our case, the model will be the cost of the items in the twelve days of Christmas; e.g., a partridge, a pear tree, a turtle dove, etc. The view is our HTML page which is responsible for displaying data. The controller is responsible for marshalling the data to the view, and helping control its state. To enable our 12 Days calculator, we will take advantage of these AngularJS features.

First, we essentially wire up our page to indicate we are going to have an Angular app by putting a ng-app attribute in the HTML body tag. Next, we set an area of our HTML markup that our controller is responsible for with a ng-controller attribute in a DIV tag.

<body ng-app="christmasApp">
<b>12 Days of Christmas Calculator</b>
<div class="container" id="12Days" ng-controller="christmasController">
...
</div>

It is worth nothing that use of data-* attributes is more "semantically" correct. If you want to save yourself keystrokes, you can just use ng-app or ng-controller, but if you get bothered by having warnings in your code, like me, you will want to use ng-app, etc.

Of course, this being Javascript and all, we need references to JavaScript files that contain this logic for implementation. Usually in structuring a project there will be an chemistryApp.js file that sets up your Angular application, controllers for interacting between your model and the view as well as services.

Our chemistryApp.js file, which we call 12DaysApp.js, is just two lines and creates the scope we reference in our body markup, christmasApp.

_12DaysApp.js _

'use strict';
var christmasApp = angular.module('christmasApp', []);

Our next Javascript file is the controller and this is where the interesting stuff is. Essentially, AngularJS has the concept of a $scope. This is essentially a glorified property bad or state manage for interacting with the page. Within our controller, we create variables on the scope for each of our items. We are grabbing costs from a USA Today story from last year (http://www.usatoday.com/story/money/business/2012/11/26/12-days-of-christmas-107k/1726807/).

To setup our controller, we create a controller with a callback such as

_christmasController.js

christmasApp.controller('christmasController',
    function christmasController($scope) {

);

Notice passing in the $scope variable on the parameter list. AngularJS does a VERY nice job with Dependency Injection. By passing in the $scope variable we are enabling its use within our controller and the HTML view. As you explore Angular, you will come to appreciate how quickly you can add services or logging, etc. with their Dependency Injection framework. We can then create a variable on the scope to set the cost for items we are getting for the 12 days of Christmas. For example, to set the price of a pear tree to $189.99 and a partridge, we have the following lines in our controller javascript $scope.pearTree = 189.99; $scope.partridge = 15.00; We then create a JavaScript function to calculate the cost of the first day. javascript $scope.day1 = function () { return parseFloat($scope.pearTree) + parseFloat($scope.partridge); }; Now, the magic of two way data binding can start, by including the AngularJS library, our application JavaScript file and our Controller JavaScript file, get two way databinding. In our HTML markup, curly braces ( {{ }} ) indicate our AngularJS model. So for the following markup, the ng-model="partridge" on our Input element says that we are two way binding the $scope.partidge value in our UI. And since this binding is part of a HTML Input box, whenever we make changes, it will update our UI. For example, we are displaying the Day 1 whatever value we initially set will be displayed. We then automatically update the value of function day1 via the function. This function is automatically updated and our UI as well whenever we type in a new value. This is pretty magical for developers who used to capture JavaScript key up and down events!

 

12 Days of Christmas

Partridge:
Day 1: {{day1()| currency:"$"}}
Pear Tree:
 
Two Turtle Doves:
Day 2: {{day2()| currency:"$"}}
Three French Hens:
Day 3: {{day3()| currency:"$"}}
Four Colly Birds:
Day 4: {{day4()| currency:"$"}}
Five Gold Rings:
Day 5: {{day5()| currency:"$"}}
Six Geese a-laying:
Day 6: {{day6()| currency:"$"}}
Seven Swans a swimming:
Day 7: {{day7()| currency:"$"}}
Eight Maids a Milking:
Day 8: {{day8()| currency:"$"}}
Nine Ladies Dancing:
Day 9: {{day9()| currency:"$"}}
10 Lords-a-Leaping:
Day 10: {{day10()| currency:"$"}}
Eleven Pipers piping:
Day 11: {{day11()| currency:"$"}}
Twelve Drummers Drumming:
Day 12: {{day12()| currency:"$"}}
Total Cost of the twelve days:
{{totalCostChristmas()| currency:"$"}}

 

christmasController.js Code

'use strict';

christmasApp.controller('christmasController',
    function christmasController($scope) {
        // http://www.irishmirror.ie/female/family/how-much-would-cost-presents-2851366
        // http://www.usatoday.com/story/money/business/2012/11/26/12-days-of-christmas-107k/1726807/
        //one
        $scope.pearTree = 189.99;
        $scope.partridge = 15.00;

        //two
        $scope.turtleDove = 62.50;

        // three
        $scope.frenchHen = 55;

        // four
        $scope.callingBird = 129.24;

        // five
        $scope.goldRing = 150;
        // six
        $scope.geese = 35;

        // seven swans
        $scope.swan = 1000.0;

        // eight
        $scope.milkingMaid = 7.25;

        // nine ladies dancing
        $scope.dancingLady = 700.0;

        // ten lords
        $scope.lord = 476.7;

        // eleven pipers at 232.91/hour
        $scope.piper = 232.91;

        // twelve drummers drumming
        $scope.drummer = 231.33;

        $scope.day1 =  function () {
            return parseFloat($scope.pearTree) +  parseFloat($scope.partridge);

        };

        $scope.day2 = function () {
            return parseFloat($scope.turtleDove) * 2;
        };

        $scope.day3 = function () {
            return parseFloat($scope.frenchHen) * 3;
        };

        $scope.day4 = function () {
            return parseFloat($scope.callingBird) * 4;
        };

        $scope.day5 = function () {
            return parseFloat($scope.goldRing) * 5;
        };

        $scope.day6 = function () {
            return parseFloat($scope.geese) * 6;
        };

        $scope.day7 = function () {
            return parseFloat($scope.swan) * 7;
        };

        $scope.day8 = function () {
            return parseFloat($scope.milkingMaid) * 8;
        };

        $scope.day9 = function () {
            return parseFloat($scope.dancingLady) * 9;
        };

        $scope.day10 = function () {
            return parseFloat($scope.lord) * 10;
        };

        $scope.day11 = function () {
            return parseFloat($scope.piper) * 11;
        };

        $scope.day12 = function () {
            return parseFloat($scope.drummer) * 12;
        };

        $scope.totalCostChristmas = function() {
            return  12* $scope.day1() + 11* $scope.day2() + 10*  $scope.day3() +  9 * $scope.day4()+ 8 * $scope.day5()+ 7* $scope.day6() +
                6 * $scope.day7() +  5* $scope.day8() +  4* $scope.day9() + 3* $scope.day10() +  2* $scope.day11() +  $scope.day12();
        };

    }
);

HTML Code

<!DOCTYPE html>
<html>
<head>
    <title>12 Days of Christmas</title>
    <link rel="stylesheet" href="css/bootstrap.min.css"/>
    <script src="angular.min.js"></script>
    <script src="12DaysApp.js"></script>
    <script src="christmasController.js"></script>
</head>
<body ng-app="christmasApp">
<b>12 Days of Christmas Calculator</b>
<div class="container" id="12Days" ng-controller="christmasController">
    <h2>12 Days of Christmas</h2>
    <div class="row">
        <div class="span6">Partridge: <input id="partridgeEle" ng-model="partridge" type="text"> Pear Tree: <input id="pearTreeEle" ng-model="pearTree" type="text"> </div>
        <div class="span2">Day 1: {{day1()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Two Turtle Doves: <input id="turtleEle" ng-model="turtleDove" type="text"> </div>
        <div class="span4">Day 2: {{day2()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Three French Hens: <input id="frenchHenEle" ng-model="frenchHen" type="text"> </div>
        <div class="span4">Day 3: {{day3()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Four Colly Birds: <input id="callingBirdElee" ng-model="callingBird" type="text"> </div>
        <div class="span4">Day 4: {{day4()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Five Gold Rings: <input id="goldRingEle" ng-model="goldRing" type="text"> </div>
        <div class="span4">Day 5: {{day5()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Six Geese a-laying: <input id="geeseEle" ng-model="geese" type="text"> </div>
        <div class="span4">Day 6: {{day6()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Seven Swans a swimming: <input id="swansEle" ng-model="swan" type="text"> </div>
        <div class="span4">Day 7: {{day7()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Eight Maids a Milking: <input id="milkingMaidElee" ng-model="milkingMaid" type="text"> </div>
        <div class="span4">Day 8: {{day8()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Nine Ladies Dancing: <input id="ladiesEle" ng-model="dancingLady" type="text"> </div>
        <div class="span4">Day 9: {{day9()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">10 Lords-a-Leaping: <input id="lordsEle" ng-model="lord" type="text"> </div>
        <div class="span4">Day 10: {{day10()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Eleven Pipers piping: <input id="pipersEle" ng-model="piper" type="text"> </div>
        <div class="span4">Day 11: {{day11()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Twelve Drummers Drumming: <input id="drummersEle" ng-model="drummer" type="text"> </div>
        <div class="span4">Day 12: {{day12()' currency:"$"}}</div>
    </div>
    <div class="row">
        <div class="span8">Total Cost of the twelve days:</div>
        <div class="span4">{{totalCostChristmas()' currency:"$"}}</div>
    </div>

</div>
</body>
</html>

This blog post originally appeared at Skyline Technologies


 

Fox Valley .NET User Group Presentation – Nov 2013

Thanks to everyone who came to my Fox Valley .NET User Group presentation last Wed, Nov 13, 2013 on AngularJS. There was a GREAT turnout! Close to 70 people showed up, which was great for a Wed night. See for yourself (and thus was early before the talk started up). It really shows the type of developers we have in Northeast Wisconsin, always learning more.

Crowd

The Fox Valley .NET User Group is expanding its scope and incorporating more technologies beyond just .NET, like Microsoft itself, who includes knockout and jQuery with Visual Studio for web development. There are a lot of tools and libraries for developers to look into and take advantage these days, way too many actuallyJ. As part of this expanding scope, the group will also be changing its name from the Fox Valley .NET User Group to something new. Currently, it may be the NorthEast Wisconsin Developer Users Group, though that may change.

As part of the expanding of scope, I thought I would embrace it and jump in with both feet. Instead of using Visual Studio, I did the entire presentation in WebStorm, a first for me. I also showed off the awesomeness of Microsoft's Azure Websites and their integration with GitHub by committing my changes and having them auto deploy during the talk. It worked pretty well, until I fell behind!

My slides are available on the blog at http://www.jptacek.com/2013/11/fvnug-presentation-nov-2013/AngularJS.pptx. All of the source code from my demo is available on my Github at https://github.com/jptacek/AngularJSFVNUG as is the PowerPoint slide deck. Finally, the Azure Website used during my presentation is available at http://loureed.azurewebsites.net/ . This link may or may not be available long term.

The group was a lot of fun. I tried my best to code up in real time with plenty of typos and many rescues from the audience. Great participation by the attendees. Lucky to be able to present and be part of the vibrant and engaged dev community in NorthEast Wisconsin. Hopefully they will have me back to talk again!


 

John Ptacek I'm John Ptacek, a software developer for Skyline Technologies. This blog is my contains my content and opinionss, which are not those of my employer.

Currently, I am reading The Dark Forest by Cixin Liu (刘慈欣)

@jptacekGitHubLinkedInStack Overflow