How to automatically tag a Git repository using NodeJs, CoffeeScript and Cake

If you have worked in a project that have several developers and several repositories, then you know that tagging can be pretty annoying.

Indeed to tag a repository you need to know two things: The latest version of your application and whether the new version contains bug fixes, new features or things that would break the backward compatibility (If following a Semantic Versioning based on MAJOR.MINOR.PATCH).

The purpose of this tutorial is to be able via a Cakefile to tag a repository using a simple task, without knowing the number of the latest version of your application.

Get this tutorial source code from GitHub

What is a Cakefile?

CoffeeScript includes a (very) simple build system similar to Make and Rake. Naturally, it’s called Cake, and is used for the tasks that build and test the CoffeeScript language itself. Tasks are defined in a file named Cakefile, and can be invoked by running cake [task] from within the directory. To print a list of all the tasks and options, just type cake.

What is Semantic Versioning?

Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

This is not a new or revolutionary idea, but by giving a name and clear definition of the above concept we ensure that the Software user is aware of your intentions.

Prerequisite

This tutorial requires several prerequisite in order to be completed successfully:

  • NodeJs must be installed
  • CoffeeScript must be installed

If those requirements are not fulfilled yet, I invite you to read a post I wrote: How to install Node.js, CoffeeScript, LESS and Uglify-js on Ubuntu

Let’s get started!

Create the needed files

For this tutorial purpose we need only two files:

Cakefile
Contains the tasks to tag the Git repository and all the logic behind it.
version
Contains the latest version of your application
If you are using Unix a simple mkdir Cakefile version would do. If you are on Windows please note that those files do not have any extension (.something) and therefore you are on our own…

Leave the Cakefile empty for now and add a line containing your application latest version (or 1.0.0) within the version file like this.

Add NodeJs packages

We will only need two NodeJs packages, the File System (fs) to read and write the version file and the Child Process (child_process) to execute command lines for us (e.g: git tag -a v2.0.1). Add the below lines to your Cakefile:

#Ā Required packages
fs      = require 'fs'
{spawn}	= require 'child_process'

Create empty tasks

We want to be able to increase the Major, the Minor or the Patch

###
TASKS
###
task 'tag.major', 'Major tag incrementation', ->

task 'tag.minor', 'Minor tag incrementation', ->

task 'tag.patch', 'Patch tag incrementation', ->

To make sure your new tasks are referenced try to run the cake command:

$ cake
Cakefile defines the following tasks:
cake tag.major            # Major tag incrementation
cake tag.minor            # Minor tag incrementation
cake tag.patch            # Patch tag incrementation

Create the methods

Our Cakefile will need four methods to be able to tag a Git repository:

tag()
The entry point method to tag repository.
run()
Execute commands.
getVersion()
Reads the version saved within the version file.
getIncreasedVersion()
Get the current version via the getVersion method and increase the major, minor or the patch.

run(cmd, args, successCallback)

The run method is pretty generic and allow us to execute wathever command needed via the spawn object. It has three parameters:

cmd
[string] The command, in our case “Git”
args
[array] The arguments, options used with the command.
successCallback
[function] Ran once the command is successfully executed.
run = (cmd, args, successCallback) ->
	# Execute the command
	child = spawn cmd, args

	# Listen to exit event
	child.on 'exit', (code) ->
		# Success
		if !code
			successCallback()

	# Listen to errors
	child.stderr.on 'data', (data) ->
		console.log 'Oups something wrong happened: ' + data

getVersion()

Reads the version saved within the version file via the NodeJs File System. It has no parameter.

# define the version file name
versionFile = 'version'
getVersion = ->
	"#{fs.readFileSync versionFile}"

getIncreasedVersion(label)

Get the current version and increase it. It has only one parameter:

label
[string] Could be: major | minor | patch
getIncreasedVersion = (label) ->
	v = getVersion()
	vSplitted = v.split('.');
	switch label
		when "major"
			vSplitted[0] = parseInt(vSplitted[0]) + 1
			vSplitted[1] = 0
			vSplitted[2] = 0
		when "minor"
			vSplitted[1] = parseInt(vSplitted[1]) + 1
			vSplitted[2] = 0
		when "patch"
			vSplitted[2] = parseInt(vSplitted[2]) + 1
	vSplitted.join('.');

tag(version)

The tag method calls the run() method with the appropriate parameters. It has only one parameter:

version
[string] The version in which you want your Git repository to be tagged.
tag = (version) ->
	run 'git', ['tag', '-a', '-m', ""Version #{version}"", version], () ->
		# Save the new version within the version file if success
		fs.writeFileSync versionFile, version

Populate tasks

Update the tasks by adding a call to the tag method.

###
TASKS
###
task 'tag.major', 'Major tag incrementation', ->
	tag getIncreasedVersion 'major'

task 'tag.minor', 'Minor tag incrementation', ->
	tag getIncreasedVersion 'minor'

task 'tag.patch', 'Patch tag incrementation', ->
	tag getIncreasedVersion 'patch'

Make a release!

Everything is now ready to execute our tasks. Let’s try shall we!

Release a Patch

$ cake tag.patch
Increasing from 1.0.0 to 1.0.1...
command used: git tag -a -m "Version 1.0.1" 1.0.1

Release a Minor

$ cake tag.minor
Increasing from 1.0.1 to 1.1.0...
command used: git tag -a -m "Version 1.1.0" 1.1.0

Release a Major

$ cake tag.major
Increasing from 1.1.0 to 2.0.0...
command used: git tag -a -m "Version 2.0.0" 2.0.0

In a next post I will continue working with this Cakefile and explain how to make a complete release of code (Minification, Packaging and Tagging). This tutorial is now finished, let me know if you liked it or not by commenting šŸ™‚

Get this tutorial source code from GitHub

Sources

Create a “load more” widget using PHP, Ajax, and jQuery

Several months ago I created a post that was quite popular: Create a “load more” widget using PHP, Ajax, Mootools, Bootstrap and Mustache.js. Today I decided to port the code from Mootools to jQuery.

Prerequisite

This tutorial requires several prerequisite in order to be completed successfully:

  • The server needs to run PHP5 to be able to use JSON functions.
  • The widget does not need any custom CSS we will only use the famous Bootstrap Framework.
  • We will use the lastest version of jQuery (1.10.1)

For the logic please refer to Create a ā€œload moreā€ widget using PHP, Ajax, Mootools, Bootstrap and Mustache.js, and to see the code refer to the demo

How to install Node.js, CoffeeScript, LESS and Uglify-js on Ubuntu

Node.js Evented I/O for V8 javascript

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Node.js allow basically to run server side JavaScript.

Installation

sudo apt-get update
# python-software-properties is needed to use add-apt-repository
sudo apt-get install python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get install nodejs

Experimenting

Node.js interpreter is available using nodejs -i

nodejs -i
> var foo = 'bar'
> console.log(foo)
bar

For convenience and because dependencies may use node command instead of nodejs, a symbolic link is necessary to avoid having this error:

/usr/bin/env: node: No such file or directory

Add Node symbolic link

sudo ln -s /usr/bin/nodejs /usr/bin/node

NPM Node Packaged Modules

NPM is Node.js package manager. We will use it to install CoffeeScript, Less and Uglify-js during this tutorial.

Installation

sudo apt-get install npm

Basic commands

# Any package can be installed by using
npm install
# Display the package list globally installed
npm list -g

CoffeeScript Little language that compiles into JavaScript

The CoffeeScript compiler is itself written in CoffeeScript, using the Jison parser generator. The command-line version of coffee is available as a Node.js utility. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser.

CoffeeScript simplify the way to create great JavaScript code.

Installation

Leave off the -g if you don’t wish to install globally.

# -g specify that you want to install it globally 
# (otherwise it will install it within a local node_modules folder)
sudo npm install -g coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http 304 https://registry.npmjs.org/coffee-script
/usr/bin/coffee -> /usr/lib/node_modules/coffee-script/bin/coffee
/usr/bin/cake -> /usr/lib/node_modules/coffee-script/bin/cake
coffee-script@1.6.2 /usr/lib/node_modules/coffee-script

Experimenting

CoffeeScript interpreter is available using coffee -i

coffee -i
coffee> foo = 'bar'
coffee> console.log foo
bar

LESS The dynamic stylesheet language

LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the server-side (with Node.js and Rhino) or client-side (modern browsers only).

Installation

sudo npm install -g less
npm http GET https://registry.npmjs.org/ycssmin
npm http 200 https://registry.npmjs.org/ycssmin
npm http GET https://registry.npmjs.org/ycssmin/-/ycssmin-1.0.1.tgz
npm http 200 https://registry.npmjs.org/ycssmin/-/ycssmin-1.0.1.tgz
/usr/bin/lessc -> /usr/lib/node_modules/less/bin/lessc
less@1.3.3 /usr/lib/node_modules/less

Experimenting

Less does not have an interpreter. To test it we will create a LESS file and compile it into CSS.

echo "@foo: 25px; #foobar{font-size: @foo};" > style.less 
sudo lessc ./style.less ./style.css
cat style.css 
#foobar {
  font-size: 25px;
}

Uglify-js JavaScript minification

UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.

Installation

sudo npm install -g uglify-js
npm http GET https://registry.npmjs.org/uglify-js
npm http 304 https://registry.npmjs.org/uglify-js
npm http GET https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.4.tgz
npm http 200 https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.4.tgz
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/source-map
npm http 200 https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http 200 https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http 200 https://registry.npmjs.org/source-map
npm http GET https://registry.npmjs.org/source-map/-/source-map-0.1.22.tgz
npm http 200 https://registry.npmjs.org/source-map/-/source-map-0.1.22.tgz
npm http 200 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/async/-/async-0.2.8.tgz
npm http 200 https://registry.npmjs.org/async/-/async-0.2.8.tgz
npm http GET https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/amdefine
npm http 200 https://registry.npmjs.org/amdefine
npm http GET https://registry.npmjs.org/amdefine/-/amdefine-0.0.5.tgz
npm http 200 https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
npm http 200 https://registry.npmjs.org/amdefine/-/amdefine-0.0.5.tgz
npm http 200 https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
/usr/bin/uglifyjs -> /usr/lib/node_modules/uglify-js/bin/uglifyjs

Experimenting

Uglify-js does not have an interpreter. To test it we will create a .js file and create a minified version .min.js from it.

touch test.js
echo "var foo = function(prefix){return prefix + ' World'}; console.log(foo('Hello'));" > test.js
# Make sure your code works
node test.js 
# it works!
Hello World
# creates the test.min.js from test.js
# -m, --mangle   :Mangle names/pass mangler options.
# -c, --compress :Enable compressor/pass compressor options.
uglifyjs test.js -mc -o test.min.js
node test.min.js
# it still works!
Hello World
# Display test.min.js content to check out the result of the minification
cat test.min.js
# The compression is not too obvious but
# it removed spaces and renamed the prefix variable
var foo=function(o){return o+" World"};console.log(foo("Hello"));

ShprinkOne WordPress theme released

I am pleased to announce the release of my first WordPress Theme: ShprinkOne is a Customizable and Responsive (mobile friendly) theme that can fit any screen (Mobile phone, tablet, laptop, desktop).

Nowadays every Internet company is focusing on mobile, it has been a trend for a long time (“mobile first” was something I heard a lot at eBay) and might continue for a little while. Releasing a theme that would not be mobile friendly was then out of the question.

As an early adopter and big fan of the front-end framework Bootstrap I decided to use its ability to create Responsive markup structure and to provide a set of great UI (Navbar, Buttons etc.), tools (Slideshow, Affix, TypeHead etc.) for this project.

Besides the obvious technical advantages that Bootstrap provides, another aspect made the choice even easier: the Community! You would be amazed by the number of start ups that based their product on Bootstrap! For example some of the ShprinkOne pages were created using jetstrap.com (great mockup tool for Bootstrap) and if you like to often change your theme ShprinkOne allows you to select some of the best Bootstrap themes (from bootswatch.com, divshot.com) that exist directly from the admin page.

For this theme I also wanted to try out Masonry and the Infinite Scroll plugins for jQuery that appeared to be really easy to use. Masonry helps to re-organize the page content and creates a Pinterest like dashboard while Infinite Scroll plugin loads more blog post when you scroll down the page. The WordPress loop page (that is shared by most of the pages: Home, Category, Tag, Author and more..) uses both of them to create a great user experience(No need to switch from page to page, everything is displayed in a single page).

ShprinkOne is Open Source and needs your help to make it even better. If you are interest to help you can fork the project on GitHub.


Screenshots


Features

  • Home page Slideshow
  • Theme customization (Select your style among 10+ free themes)
  • Layout customization (Sidebar-Content, Content-Sidebar or Content)
  • Posts as pins using Masonry
  • Language ready: So far English and French

Get the full list

Twitter Bootstrap: Error compiling mixins.less with lessphp

If you are trying to compile Twitter Boostrap v2.3 CSS using less and lessphp v0.3.8 you have probably faced a “500 Internal Server Error” message.

It is due to a bug on lessphp side. Bootstrap uses less.js and does not support lessphp.

To fix the problem you will need to open mixins.less file and make a change on the following 6 lines.

mixins.less original file

.span@{index} { .span(@index); } // line:578
.offset@{index} { .offset(@index); } // line:584
.span@{index} { .span(@index); } // line:623
.offset@{index} { .offset(@index); } // line:629
.offset@{index}:first-child { .offsetFirstChild(@index); } // line:630
input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); } // line:678

mixins.less fixed

(~".span@{index}") { .span(@index); } // line:578
(~".offset@{index}") { .offset(@index); } // line:584
(~".span@{index}") { .span(@index); } // line:623
(~'.offset@{index}') { .offset(@index); } // line:629
(~'.offset@{index}:first-child') { .offsetFirstChild(@index); } // line:630
(~"input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index}") { .span(@index); } // line:678

Sources

Create a “load more” widget using PHP, Ajax, Mootools, Bootstrap and Mustache.js

3 years ago David Walsh created an awesome (his words, but I agree!) NetTuts post called Create a Twitter-Like “Load More” Widget which is still today a reference on learning how to create “load more” widgets.

Today, with the emergence of projects such as Bootstrap (that took the web by a storm) and Mustache.js creating such a widget is getting easier.

Prerequisite

This tutorial requires several prerequisite in order to be completed successfully:

  • The server needs to run PHP5 to be able to use JSON functions.
  • The widget does not need any custom CSS we will only use the famous Bootstrap Framework.
  • We will use the lastest version of Mootools Core (1.4.5) and the Fx.Scroll Class from Mootools More.
  • To finish we will need to use the JavaScript version (Mustache.js) of the great Mustache project.

Step 1: PHP/MySQL

The PHP part is more or less what David Walsh created.

Start session

By using session the widget will remember how many posts you loaded during the last visit (in case you open a new page and come back).$_SESSION['posts_start'] is initialised and represent the number of posts already loaded in the page (by default two posts are directly loaded).

/* settings */
session_start();
$number_of_posts = 2; //2 at a time
$_SESSION['posts_start'] = $_SESSION['posts_start'] ? $_SESSION['posts_start'] : $number_of_posts;

Get posts from the Db

The function get_posts has two optional parameters ($start is increased every time you push the “more” button) to get only the posts you wish for.

/* grab stuff */
function get_posts($start = 0, $number_of_posts = 2) {
	/* connect to the db */
	$connection = mysql_connect('localhost','username','password');
	mysql_select_db('db_name',$connection);
	$posts = array();
	/* get the posts */
	$query = "SELECT post_title, post_content, post_name, post_date, ID FROM wp_posts WHERE post_status = 'publish' ORDER BY post_date DESC LIMIT $start,$number_of_posts";
	$result = mysql_query($query);
	while($row = mysql_fetch_assoc($result)) {
		// Remove html tag and truncate the content
		$row['post_content'] = substr(strip_tags($row['post_content']), 0,200) . '...';
		$posts[] = $row;
	}
	/* return the posts in the JSON format */
	return json_encode($posts);
}

Set up the JSON API

The purpose of the following piece of code is to return the desired posts in a JSON format for our widget convenience. If the $_GET['start'] variable is set in the requested URL then we know it has been requested from our widget(via AJAX request). It will then return posts and die.

You could also use the great JSON API plugin

/* loading of stuff */
if(isset($_GET['start'])) {
	/* spit out the posts within the desired range */
	$posts = get_posts($_GET['start'],$_GET['desiredPosts']);
	// decode the result to know the exact length of the result
	// It could be 2, 1 or 0 in this case
	$postsDecoded = json_decode($posts);
	// If the result is not empty we update the session
	if (!empty($postsDecoded))
	{
		/* save the user's "spot", so to speak */
		$_SESSION['posts_start']+= count($postsDecoded);
	}
	echo get_posts($_GET['start'],$_GET['desiredPosts']);
	/* kill the page */
	die();
}

Step 2: HTML (Bootstrap markups)

Our widget HTML is fairly simple. It contains a title with a posts counter (#widget .badge),a posts container (#widget .content) and a more button (#widget .more).

<div id="widget">
	<h4 id="widget-title">
		Widget Title <span class="badge badge-info"><?php echo $_SESSION['posts_start'] ?>
		</span>
	</h4>
	<div class="content" style="height: 300px; overflow: auto; margin: 0px;"></div>
	<button class="more btn btn-block">
		More <span class="caret"></span>
	</button>
</div>

Step 3: Mustache template (Bootstrap markups)

The mustache template contains the HTML for posts. The block {{#data}} YOUR HTML {{/data}} is rendered once for each item in the list ({data:[]} see below in the JavaScript part).

The inverted section opens with {{^data}} instead of {{#data}}. The block of an inverted section is rendered only if the value of that section’s tag is null, undefined, false, or an empty list.

For more details please check the Mustache.js documentation.

{{#data}}
<div class="item">
	<img class="thumbnail pull-left" width="50px" height="50px" src="http://placehold.it/50x50" style="margin: 0px 10px 5px 0px;">
	<a href="#">
		<h4 style="margin: 5px 0px;">{{post_title}}</h4>
	</a>
	<p>
		<small>{{post_content}}</small>
	</p>
	<div class="well well-small">
		{{post_date}}
	</div>
</div>
{{/data}}
{{^data}}
	<div class="alert alert-error">No data</div>
{{/data}}

Step 4: Mootools JavaScript

Initialize variables

  • The start variable represent the number of posts already loaded in the page.
  • The initialPosts variable is an array containing posts (either the default number of posts or the last number of posts saved in the session).
  • The desiredPosts variable is here 2 (See the PHP part above).
  • The template variable is either NULL or contains the Mustache template String.
var start = <?php echo $_SESSION['posts_start']; ?>;
var initialPosts = <?php echo get_posts(0,$_SESSION['posts_start']);  ?>;
var desiredPosts = <?php echo $number_of_posts; ?>;
var template = null;

DOM elements

// Widget element
var widget = $('widget'),
// Element to load the posts
content = widget.getElement('.content'),
// the more button
more = widget.getElement('.more'),
// the post counter
counter = widget.getElement('.badge');

Post Handler

The postHandler function purpose is to inject posts into our HTML.

The first execution loads and stores the Mustache template file (via a synchronous Ajax request) then uses the function Mustache.render(template, {'data' : data}) (that returns a HTML String of our posts) to populate the widget HTML.

Next executions (when clicking the “more” button) skip the Ajax request on the template and simply populate the widget HTML.

var postHandler = function(data){
	// Check if the template is already stored
	if (!template){
		// If not we get it
		new Request({
			url: 'load-more.mustache',
			method: 'get',
			async: false,
			onSuccess: function(responseText){
				// the response text is stored as the template
				template = responseText;
			},
			onFailure: function() {
				// insert the failure message
				widget.grab(alerts.templateFailure,'before');
				// get rid of the widget
				widget.dispose();
			}
			// Send the Ajax request
		}).send();
	}
	else{
		// Set the progress bar to 100%
		progressBar.setStyle('width', '100%');
		// Delay the normal more button to come back for a better effect
		more.set.delay(500, more, ['html','More <span class="caret"></span>']);
	}
	// Transform the template (String) into Elements that we can use
	var childrens =  new Element('div', {
		// Mustache requires an object property to reference in order to
		// create loops
		'html' : Mustache.render(template, {'data' : data})
	}).getChildren('*');
	// insert childrens at the end of the content element
	content.adopt(childrens);
	// Scroll to the first element loaded
	scroll.toElement(childrens[0]);
}

Ajax request to get the data

This part of code (I kept only the logic and removed effects) create a Ajax request instance for the more button to use when clicked. We ask the same page to return raw data (JSON) and on success event we either load this data into our template (if responseJSON.length > 0) or remove the more button (no more data to load).

// create the data Ajax request
var request = new Request.JSON({  
	url: 'load-more.php', // ajax script -- same page
	method: 'get',
	// Any calls made to start while the request is running will be ignored.
	link: 'ignore',
	// We do not want IE to cache the result
	noCache: true,
	onSuccess: function(responseJSON) {
		// Check if data is returned
		if (responseJSON.length > 0){
			// Update the total number of items
			start += responseJSON.length;
			// load items on the page
			postHandler(responseJSON);
		}
		else{
			// Remove the more button
			more.dispose.delay(500,more);
		}
	}
});

Add the click event to the “more” button

// add the click event to the more button
more.addEvent('click',function(){  
	// begin the ajax attempt
	request.send({
		data: {  
			'start': start,  
			'desiredPosts': desiredPosts  
		} 
	});  
});

Complete JavaScript

I extensively commented the following code to be as clear as possible. If you are having problems to understand just leave a comment, I will get back to you.

//domready event  
window.addEvent('domready',function() {
	// initialize variables
	var start = <?php echo $_SESSION['posts_start']; ?>;
	var initialPosts = <?php echo get_posts(0,$_SESSION['posts_start']);  ?>;
	var desiredPosts = <?php echo $number_of_posts; ?>;
	// either null or contains the mustache template
	var template = null;
	// Widget element
	var widget = $('widget'),
	// Element to load the posts
	content = widget.getElement('.content'),
	// the more button
	more = widget.getElement('.more'),
	// the post counter
	counter = widget.getElement('.badge');
	// Create alerts elements (Display Success or Failure)
	var alerts = {
			templateFailure : new Element('div',{'class' : 'alert alert-error','html' : 'Could not get the template.'}),
			requestEmpty : new Element('div',{'class' : 'alert alert-info','html' : 'No more data'}),
			requestFailure : new Element('div',{'class' : 'alert alert-error','html' : 'Could not get the data. Try again!'})
	}
	// create the Bootstrap progress bar element
	var progressElement = new Element('div', {
		'class': 'progress',
		'html': "<div class='bar'></div>",
		'styles': {
			'margin-bottom' : 0
		}
	});
	var progressBar = progressElement.getElement('.bar');
	// Create a scroll instance on the widget content
	// This Class is included in Mootools More
	var scroll = new Fx.Scroll(content, {
		duration: 1000,
		wait: false
	});
	// function that handle posts
	var postHandler = function(data){
		// Check if the template is already stored
		if (!template){
			// If not we get it
			new Request({
				url: 'load-more.mustache',
				method: 'get',
				async: false,
				onSuccess: function(responseText){
					// the response text is stored as the template
					template = responseText;
				},
				onFailure: function() {
					// insert the failure message
					widget.grab(alerts.templateFailure,'before');
					// get rid of the widget
					widget.dispose();
				}
				// Send the Ajax request
			}).send();
		}
		else{
			// Set the progress bar to 100%
			progressBar.setStyle('width', '100%');
			// Delay the normal more button to come back for a better effect
			more.set.delay(500, more, ['html','More <span class="caret"></span>']);
		}
		// Transform the template (String) into Elements that we can use
		var childrens =  new Element('div', {
			// Mustache requires an object property to reference in order to
			// create loops
			'html' : Mustache.render(template, {'data' : data})
		}).getChildren('*');
		// insert childrens at the end of the content element
		content.adopt(childrens);
		// Scroll to the first element loaded
		scroll.toElement(childrens[0]);
	}
	// place the initial posts in the page
	postHandler(initialPosts);

	// create the data Ajax request
	var request = new Request.JSON({  
		url: 'load-more.php', // ajax script -- same page
		method: 'get',
		// Any calls made to start while the request is running will be ignored.
		link: 'ignore',
		// We do not want IE to cache the result
		noCache: true,  
		onRequest: function() {
			// Set the progress bar to 0%
			progressBar.setStyle('width', '0%');
			// remove the more button innerHTML and insert the progress bar
			more.empty().grab(progressElement);
		},
		onSuccess: function(responseJSON) {
			// Check if data is returned
			if (responseJSON.length > 0){
				// Update the total number of items
				start += responseJSON.length;
				// Update the counter
				counter.set('html', start);
				// load items on the page
				postHandler(responseJSON);
			}
			else{
				// insert the empty message
				widget.grab(alerts.requestEmpty,'before');
				// Set the progress bar to 100%
				progressBar.setStyle('width', '100%');
				// Remove the more button
				more.dispose.delay(500,more);
				// remove the empty message after 4 seconds
				alerts.requestEmpty.dispose.delay(4000,alerts.requestEmpty);
			}
		},
		onFailure: function() {
			// insert the failure message
			widget.grab(alerts.requestFailure,'before');
			// Set the progress bar to 100%
			progressBar.setStyle('width', '100%');
			// Delay the normal more button to come back for a better effect
			more.set.delay(500, more, ['html','More <span class="caret"></span>']);
		}
	});
	// add the click event to the more button
	more.addEvent('click',function(){  
		// begin the ajax attempt
		request.send({
			data: {  
				'start': start,  
				'desiredPosts': desiredPosts  
			} 
		});  
	});
});

Xampp – Open SSL – Don’t know how to get public key from this private key

When enabling OpenSSL you might get this error message if you use Xampp on Windows. Follow this steps to resolve the problem:

  1. Stop your Apache.
  2. In the folder `xamppphp` you will find two DLL: libeay32.dll and ssleay32.dll. Copy them into the folder `xamppapachebin`
  3. Open the `xamppphpphp.ini` file and remove the semicolon in front of `extension=php_openssl.dll`
  4. Start you Apache

Dependency injection

The Dependency Injection is a complicated term that define a simple idea everybody is using with or without knowing it.

I will try in this post to share the essential and explain it as simple as possible.

What is Dependency Injection (DI)?

A DI is a popular design pattern for large scale Software. The purpose is to simplify the deployment and the Unit tests. However to do so you will need to create a more complex architecture! Before using this design pattern ask yourself if you need it. If your Software can be used on different platforms and configurations you probably need it, if not then it is up to you.

Exemple using PHP

Let’s say your Software is about boats and in order to create a boat Object you need to establish a Database connection.

You naturally create

Class Boat
{
	public function __construct()
	{
		$this->db = new Database('myHost', 'myDb', 'myUser', 'myPassword');
	}
}

As you can see in that example the Boat Class instantiate itself the Database instance with its own parameters. Boats Objects are dependant on the Database Class and its four hard-coded parameters. Without them the database connection is corrupted.

In the future let’s say that you have more Objects that use the same code across your platform. You have Boat, Car, Bus, Plane etc. with the same hard-coded dependency.

If you want to change the Database parameters you will need to go to all your files and change the dependency. This is really bad behaviour when it comes to fair large Software.

Class Boat
{
	public function __construct(String $host, String $db, String $user, String $pass)
	{
		$this->db = new Database($host, $db, $user, $pass);
	}
}

Now we added parameters to the constructor. The same four values are now provided by the piece of code that creates the Boat instance. If you want to change the Database parameters in the future you will not have to change Boat code.

Are we done? Well this is a bit better but our Boat Class is still depending on the Database Class and the four same values.

What happen if in the future you want to use another Database Class? Well once again you will need to change your code…We can do better than that!

Class Boat
{
	public function __construct(Object $db)
	{
		$this->db = $db;
	}
}

In this example our Boat Class is no longer dependent on the Database Class or the four previous values! The piece of code that creates a Boat Class has to inject the Database Object.

Sources

WordPress add_image_size cropping problem: How to enable GD library

While trying to enable the image resizing option in WordPress I figured that the cropping feature of the function below (located in /wp-includes/media.php) did not work on my localhost.

function add_image_size( $name, $width = 0, $height = 0, $crop = false )

Using the code below inĀ functions.php I was able to resize images (really badly though) but unable to crop them.

//This feature enables post-thumbnail support for a Theme
add_theme_support( 'post-thumbnails' );
add_image_size( 'post-image',  708, 400, true );
add_image_size( 'post-image-large',  708, 200, true );
add_image_size( 'post-image-small',  330, 150, true );

After some research I found a solution. In order to solve the cropping problem you will need to install the GD Library.Ā GD is an open source code library for the dynamic creation of images. It supports JPG, PNG and XPM formats. Here is how to install it:

For Windows

All you need to do is to uncomment (remove the semi-colon at theĀ beginningĀ of the line) the line below on your php.ini

;extension=php_gd2.dll

Once it is done save it and do not forget to restart your Apache server.

For Linux

At first I tried to follow the Windows step but I got this error message:

Warning: PHP Startup: Unable to load dynamic library
'/opt/lampp/lib/php/extensions/no-debug-non-zts-20090626/php_gd2.dll'
 - /opt/lampp/lib/php/extensions/no-debug-non-zts-20090626/php_gd2.dll:
 cannot open shared object file: No such file or directory in Unknown on line 0

For Linux it is a little bit more complicated than only uncomment a line. To get it work you will have to install the library with the line below.

apt-get install php5-gd

Then restart Apache and it should work fine.

/etc/init.d/apache2 restart

or if you are using LAMPP/XAMPP

/opt/lampp/lampp restart

Once you have done all of this cropping should work for newly uploaded images. Unfortunetly you will need to re-processĀ old pictures. To do so a great solution is to use the Regenerate Thumbnails plugins for WordPress.

Sources: