Hosted ElasticSearch (2017 edition)

ElasticSearch offers an excellent alternative when you need to implement a better alternative to MySQL FULLTEXT search, with nice features such as related results, facets, “did-you-mean” and many, many options to control exactly what you need to get from it.

Unfortunately, as your data grows it also becomes harder to host on your own and keep focusing on your product rather than the operation of your search cluster, which it’s why there are several services that can take care of this.

Here’s some of them and their main differences.

Continue reading “Hosted ElasticSearch (2017 edition)”

Simple, automated and low cost MySQL backup strategy

Setting up a mysql backup strategy it’s hardly an exciting task, so having a simple solution it’s key to actually get it out of your to-do list.

Here’s a simple, automated and low-cost alternative that I use to keep MySQL database backups of small to medium-sized projects.

Setting up automatic backups

automysqlbackup it’s a simple shell script that automates the creation of daily, weekly and monthly MySQL backup.

It’s available on the repositories for Debian and Ubuntu. The project it’s officially hosted on SourceForge but you can also find lots of several of forks hosted on GitHub.

If you’re using Ubuntu, the installation it’s completely straightforward; all you need it’s sudo apt install automysqlbackup and you’re done.

Backups are saved on /var/lib/automysqlbackup, organized by daily/weekly/monthly directories and then by database name.

There are a few settings that you can modify on /etc/default/automysqlbackup, such as the backup dir, whether to send informative e-mails or to keep a “latest” directory.

Off-site backups

Of course, having automated backups it’s just part of the solution: you need to keep an off-site copy of your data in case your server it’s compromised.

A very simple and cheap alternative it’s using Google Drive as external storage: for USD 1.99 you get 100 GB which are shared with other Google services such as Photos and Gmail, but even the free 15 GB are plenty.

For saving your backups to Drive you can use drive, which it’s a tiny program to pull or push files to the service. There are several platform packages for various distributions.

After the installation, you need to initialize the client, so you can get an OAuth token to authorize the application access to your Drive account.

The client doesn’t do synchronization, it trusts the user to determine the authoritative version of a file or folder, which might be problematic in some cases but it’s specially useful for copying the backups, since that will automatically take care of deleting older backups —which you can still find on your “Trash” for 30 days since deletion.

You can set a daily cron job to upload your latest backups using something like this:

25 4 * * * cd /root/gdrive/mysql-backups && drive push -no-prompt

Best way to initialize a class on a WordPress plugin

When you’re developing a WordPress plugin, there are certain patterns and practices that are extremely useful to know and apply in order to get a better fit with the platform as a whole.

One of these things it’s what’s the better way to initialize a class on a plugin, which this answer on the WordPress StackExchange covers in great detail, while also explaining other interesting topics and recommendations such as using an autoloader and global access, registry and service locator patterns.

While you’re at it, you might also want to check these posts from Tom McFarlin:

 

Pixel Density, Demystified

…or “what you must know about designing for retina display and high-density screens”.

Pixel density it’s an often misunderstood subject: some people think that the solution it’s just to design everything at twice the size that they used to, but actually it’s a little simpler and more complicated than that… at the same time.

Be sure to also check the text version on Medium and remember:

  1. Design in vector shapes
  2. Design at “1x”

 

The greatest countries and administrative subdivisions database ever

The United Nations Code for Trade and Transport Locations it’s probably the greatest countries, states, regions, cities and localities database you can ever find; or at least the most complete you might hope for. It includes over 100,000 locations in 249 countries with detailed administrative subdivisions info and even geographic coordinates (rough, but still).

Getting response headers data from an AJAX request with javascript

Response headers can contain valuable information and may help to keep your API responses simpler by separating the actual response data from accessory metadata.

For instance, when querying the WordPress JSON API for a list of posts, the response body includes just the posts data but the pagination info it’s sent as headers:

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Authorization
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
X-WP-Total: 7
X-WP-TotalPages: 2

Whether you’re using jQuery or just plain Javascript, it’s quite simple to get response headers.

Using jQuery

I’ll keep using the same case of getting a list of posts from the WordPress API.

The jQuery code for the AJAX request would look something like this:

var posts = $.ajax({
  type: 'GET'
  url: '/wp-json/wp/v2/posts/',
  data: {
    'per_page': 10
  }
});

In jQuery, an AJAX request returns a promise, so after that we could do something like:

posts.done( function( data, textStatus, jqXHR ){
  var receiver = $('#posts-receiver');
  for ( var i in data ){
    receiver.append( data.title.rendered +':'+ data.link );
  }
  var current_page = parseInt( receiver.data('paged'), 10 ),
      total_pages  = parseInt( jqXHR.getResponseHeader('X-WP-TotalPages'), 10 );
  if ( curent_page == total_pages ) {
    $('button#load-more-posts').attr('disabled', 'disabled');
  }
} );

The jqXHR object it’s a superset of the native XMLHttpRequest object. It exposes a jqXHR.getResponseHeader() method for getting a single response header (which it’s always returned as a string) and jqXHR.getAllResponseHeaders() for getting all of them as a single string.

Using plain javascript

The same getResponseHeader method is available in plain javascript as part of the XMLHttpRequest object; the only thing that changes it’s the way you create and initiate the request:

var request = new XMLHttpRequest;
request.open('GET', '/wp-json/wp/v2/posts', true);
request.onload = function(){
  // do some stuff
  var total_pages = parseInt( request.getResponseHeader('X-WP-TotalPages), 10 );
};
request.send();