Create A VirtualHost And Install WordPress Automatically

In my testing and building efforts I frequently find myself creating a virtual host like http://myproject.local. It takes a few minutes but apart from a couple of strings it’s always the same process. Time for a bash script that does this for us!

I wrote a script that automates the task of creating a directory for the website, creating the config file, enabling the site, restarting the server and installing WordPress. There are a couple of prerequisites and a few things to be aware of so before you run it, do read my notes after the code.

You invoke the bash script like this:

sudo bash make_site.sh mysite local yes

The three parameters are:

  • The name of the site
  • The TLD of the site
  • Wether or not you want the WordPress install

The result of this command will be a website at mysite.local with WordPress installed and running. There are a few things to note before running this script:

  • It will create the folder for the website at /var/www/html/website_name. If you have a different setup, change the folder in line 2, the DocumentRoot on line 12 and the Directory directive on line 17.
  • You must have WP-CLI installed for the WordPress install to work.
  • If you do not want the WordPress install just omit the third parameter. Setting it to no or false will notwork.

The script does the following things:

  • Creates a directory for the site
  • Adds a config file for the site
  • Enables the site and restarts the server
  • Optionally installs WordPress
    • The user and password for the database is set to root because that’s what it is on my Vagrant box. Change this on line 37 if needed
    • The database name is the same as the site name. Change this on line 37 if needed
    • Change the details of your admin user on line 39
    • The Hello Dolly And Akismet plugins are removed

If you have any idea to make this better I’m all ears!

Easy Featured Images

I’ve always been a bit frustrated at the way featured images are assigned (you need to go into the single edit page) so I decided to do something about it. Easy Featured Images is the result of my thought processes, give it a go, it’s free of course!

It support all post types so it should work for any custom stuff you have as well. The only caveat is if the plugin that creates the custom post type has already added support for viewing thumbnails. I’ve already looked at WooCommerce so you should be all set there. If you do see any issues, please use the support page of the plugin to submit them.

If you’re interested in how the plugin works, how the code is put together, you can read my article on WPMU DEV about the plugin. You can also take a look at the plugin’s Github repository – clone away!

Running PHP From The Command Line On Windows

Since I work on a Mac I never really though much about the php command, it was always just there. While writing an article for tuts I had to figure things out on Windows as well and I realized that running php there is not trivial.

Why would you want to be able to run php from the command line anyway? One example would be to translate a plugin using the WordPress i18n Tools which require you to issue a php command. Another is running a PHP server via a Node package such as Grunt.

Installation is not that difficult and it forced me to learn new things on Windows which is always great. Here’s how I did it:

First of all, you need to grab PHP from the PHP Download page. There are a couple of versions there, here’s a quick guide to choosing. If you’re on a 32bit system choose an x64 version. If you are on a 64bit system (most modern computers) use the x86 version. If you are installing on Windows use the Non Thread Safe version, for all other system use the Thread Safe version. So for a modern Windows installation you’ll the first one which is currently: VC11 x86 Non Thread Safe.

Extract the downloaded file somewhere, I used C:/ and I named the folder php. The php folder should have a bunch of files in it, among them php.exe. What we need to do is add this to our path. To do that we need to create a file in any folder already added to our path. You can display folders added to your path with the following command:

echo %path%

If this doesn’t contain any folders that allow you to create files you’ll need to add a custom folder. You can add a folder to your path by following the instructions here, the process differs for different versions of Windows. On my end, I added an environment folder into my user directory.

In this folder create a file named path_php.cmd and add the following contents (change the folder to the actual one on your system).

<code class='language-bash'>PATH=%PATH%;C:\Users\danielpataki\environment
php -v

Now restart the cmd, navigate to the created folder and type path_php. Restart cmd again and php should now be available, yay!

Making Synchronous AJAX Calls With jQuery

Most of the time we want to make asynchronous AJAX calls, this is kind of the point of using AJAX at all. However, in some rare cases it may be necessary to wait for the result before proceeding. What we need is the async parameter that $.ajax() offers but the implementation is not that obvious.

The Case For Synchronous Calls

In my particular case I’m building a a registration form wizard. When you type your email it gets sent to the server which checks if the address has already been used. If it has, it will display a nice little error message:

Sign Up Wizard With Error

So far so good, but what happens when you click the next button which would take you to step 2? The wizard aspect of the form is handled by a separate script which “turns the page” when you click the button. The way around this is to use event.stopImmediatePropagation(); on click, stopping the click event in its tracks.

The plan is to validate the form again when the user clicks the button. If something is invalid we display the messages and stop propagation. If all is well we don’t do anything, the wizard can go ahead and do its job.

The problem is that since the email validation is done asynchronously it will never return the proper value to us unless we actually wait for the request to finish.

Making an Asynchronous Call

The place where most people trip up is how they return the results. Here is a the logical looking but incorrect way:

function validate_email() {
    $.ajax({
        url: ajaxurl
        type : 'post',
        async: async,
        data: {
            action: 'check_mail',
            email: $('#email').val()
        },
    })
    .done( function( response ) {
        if( response === 'valid' ) {
            return true;
        }
        else {
            return false;
        }
    })
}

The return values in the done() callback are in a different scope and will not return the data as you would think, you need to pass the value to the function’s return value, something like this:

function validate_email() {
    result = false;
    $.ajax({
        url: ajaxurl
        type : 'post',
        async: async,
        data: {
            action: 'check_mail',
            email: $('#email').val()
        },
    })
    .done( function( response ) {
        if( response === 'valid' ) {
            result = true;
        }
        else {
            result = false;
        }
    })

    return result;
}

Now the function will return your AJAX calls synchronously. Beware that this should only be used when absolutely necessary as processing will stop until the result is returned which could lead to websites freezing up.

Aggregate Your Feeds With Yahoo Pipes

I quite like Feedly for reading up on stuff that interests me but recently I needed to create an RSS feed out of other RSS feeds. After looking at IFTTT which fails to offer this functionality and Zapier which would charge me $20/month for it I settled on the free Yahoo Pipes.

Why Aggregate Feeds

There are any number of reasons you might want to do this. In my case, I wanted to display a list of my posts elsewhere in the sidebar on the left. I write for 5-6 websites and I just wanted to show my own posts. This is a challenge because:

  1. You have to pull in information from 5-6 sources
  2. One website doesn’t have an author feed

You may want to do the same if you like a particular author or a particular category across multiple sites. You could also create some keywords which would pull posts from your designated sources when they appear in them.

A big benefit of assembling an aggregate feed is that it plays nice with default functionality such as the WordPress feed widget. You could write a widget of your own which takes a number of feed URLs and figures out which items to show but this would take time and maintenance. The end result of using Pipes is a single RSS feed you can pass to any application.

Working With Yahoo Pipes

Yahoo Pipes looks a database GUI, it allows you to create a process involving data sources. Perhaps showing the end result first will help you understand how this works.

A screenshot from the Yahoo Pipes app

First, I pulled a Fetch Feed module from the input sources section and added the URLs I need (just click the +URL link). For sites which don’t have an author feed I needed to filter out articles not written by myself.

To this end I added a Filter from the operators section. All I permit are items where the dc:creator property is Daniel Pataki. I know the property name by clicking on an item in the debugger pane at the bottom.

The feed isn’t sorted by date by default – it looks like it’s sorted by source and then by date – so I added a Sort module from the operators section. I chose a property to order by and the sort order.

If you save this and run it or go back to the my pipes section and select it you should see details on the left, results on the right and some info on the top right. The info includes a Get as RSS which is just what we need – all done!

Other Pipes

Yahoo Pipes is a flexible tool which allows you to do a number of neat things. Take a look at the popular pipes page for Webpate-to-RSS, Ebay, Amazon, Craigslist price watches Stock watches and more.

WordPress Upload Issues With Vagrant

It may be just my setup but if I create a virtual machine using Vagrant I usually end up with a WordPress installation that has trouble uploading files due to permission issues. This can be solved by setting the owner and the group in the Vagrantfile but this isn’t ideal.

If I set the owner and group to www-data WordPress works fine, but I need to sudo my commands in the terminal, even for a simple file creation operation. I finally had some time to figure this out and it turns out it isn’t that difficult.

You’ll need to edit the /etc/apache2/envvars file in your virtual machine. Find the APACHE_RUN_USER and APACHE_RUN_GROUP variables and make sure vagrant is used for both:

export APACHE_RUN_USER=vagrant
export APACHE_RUN_GROUP=vagrant

Once this is added, make sure to restart your server using sudo service apache2 restart and everything should be dandy. The terminal won’t scream for sudo all the time and WordPress will upload images/plugins/themes and such without a hitch.

Grunt Bus Error

While using grunt, more specifically the grunt-contrib-watch package I stumbled on a weird error. When I used grunt watch everything was dandy, but as soon as a change took place the script exited with a bus error.

According to the close notice on this issue, a similar issue was settled by updating node. The upgrade can be done via npm like so:

sudo npm cache clean -f
sudo npm install -g n
sudo n stable

That’s all there is to it, if you get a similar error try updating node, perhaps everything will pop back into place.

(Thanks to David Walsh for the upgrade method)

WordPress File Permission, Ownership And FTP Uploads

Do you have a WordPress website which won’t allow you to install and activate themes and plugins from the repository without asking for FTP data? This can be pretty annoying, especially during development where you may want to switch themes and plugins pretty often.

The solution to this problem is grossly misunderstood because this is not a file permission issue, it is actually a file ownership issue. You could change your file permissions to 777 and it still wouldn’t work, you’ll need to use chown to change the ownership of your files.

WordPress makes sure that the owner of the files is the same as the apache user. This is usually your user account, not root. So first of all, why can these sometimes be out of sync?

In my case this happened because I used a root login to gain ssh access to my server and upload an unzip WordPress. This created all the files and folders necessary but since I was logged in as root, the files and folders are owned by root.

Using the following command you can list all users in the account:

awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd

you’ll need to select your user. This usually has something to do with your main domain, you may need to experiment a bit.

Once you know the user you’ll need to navigate to the root directory of your installation and issue a command like this:

chown username:group * -R

username should be the username you want to take ownership of the files and group is the group you’d like to use. I’m not sure what you should put there, I used root. I think this is safe, but I’m still checking.

In any case, once this command has been issued you can use ls -l . to show all permissions and you should see the change. Then, visit the theme install page and all should be well.

WordPress Plugin Activation Checks

I’ve noticed through our customers on Themeforest that quite a number of people have very old versions of PHP running on their servers. I’m talking pre 5.3 here which is now almost 5 years old. Here’s a quick way to make sure the plugin can’t be activated in this case, along with a friendly message.

function my_activation_check() {

	$php = '5.3';

	if ( version_compare( PHP_VERSION, $php, '<' ) ) {
		deactivate_plugins( basename( __FILE__ ) );
		wp_die(
			'<p>' .
			sprintf(
				__( 'My Awesome Plugin can not be activated because it requires a PHP version greater than %1$s. Your PHP version can be updated by your hosting company.', 'textdomain' ),
				$php
			)
			. '</p> <a href="' . admin_url( 'plugins.php' ) . '">' . __( 'go back', 'textdomain' ) . '</a>'
		);
	}

	return;

}
register_activation_hook( __FILE__, 'my_activation_check' );

If you require a specific WordPress version you could include that as well in a similar fashion.

Standardizing Custom And Default WordPress Menus

I’ve wanted to get around to standardizing WordPress menus for a while now. When you use the wp_nav_menu() function and the user does not have a default menu set for the location in question the wp_page_menu() function will be used. This function outputs a different structure and uses different classes. This makes it harder to style menus consistently with CSS.

Here’s a little snippet I worked on which tries to standardize these two WordPress menus. It’s still in beta, I’m testing it for a new theme so if you find any problems please do let me know.

function dp_nav_menu(){
	$menu = wp_page_menu( array(
		'menu_class' => 'menu-container',
		'echo'       => false
	));

	$menu = str_replace(
		array(
			'current_page_item',
			'current_page_parent',
			'current_page_ancestor',
			'<ul>',
			'page_item',
			'<ul class=\'children\'>'
		),
		array(
			'current-menu-item',
			'current-menu-parent',
			'current-menu-ancestor',
			'<ul class="menu">',
			'menu-item',
			'<ul class="sub-menu">'
		),
		$menu
	);

	echo $menu;
}

This should allow you to use roughly the same classes for both WordPress menus. Here are the things that are changed in the default menu:

  • sub menus have the ‘sub-menu’ class instead of the ‘children’ class
  • current items have the ‘current-menu-item’ class instead of the ‘current_page_item’ class
  • parent items have the ‘current-menu-parent’ class instead of the ‘current_page_parent’ class
  • item ancestors have the ‘current-menu-ancestor’ class instead of the ‘current_page_ancestor’ class

This function needs to be called as the fallback function of the wp_nav_menu() function, something like this:

$args = array(
	'theme_location'  => 'header_menu',
	'fallback_cb'     => 'dp_nav_menu',
);

wp_nav_menu( $args );