26 March 2017

Tweaking the vertical position of an image

Positioning images/icons alongside text or other elements can be tricky. The following CSS will allow you to slide the image along the vertical axis.

.something img {
    position:relative;
    top:50%;
    transform:translateY(-35%); /* play with this */
}

23 February 2017

Running CodeIgniter in Heroku

Note: This does not include a database setup.

Grab a copy of the latest codeigniter and navigate to the root folder

cd diylingo/CodeIgniter-3.1.3/

Login to heroku

heroku login

Add git

git init

Identify heroku as the remote repository for git to use

heroku create diylingo

In codeigniter, open config.php and add the heroku address outputted from the create command to

$config['base_url'] = 'https://diylingo.herokuapp.com/';

Because this will be detected as a php app and there is a composer.lock file which demands you satisfy all dependencies, you'll need to run

composer update

Now prepare the files for upload

git add .

git commit -m "initial commit"

Push your code to the remote heroku git repository

git push heroku master

Check the result

open heroku

You should have the CodeIgniter welcome page opened for you in the browser.

16 February 2017

Getting started with pagination in CodeIgniter

Intro

Sometimes your database can return a lot of data. Like hundreds (or even thousands) of rows that may need to be outputted to the user. In these kinds of situations, it’s good to use pagination, which codeigniter has an built-in library for.

Pagination is the process of dividing this data into chunks, like pages in a book. On your webpage, this often looks like a series of clickable number links, but can also be formatted to just previous and next links. Behind the scenes though, pagination works with SQL’s LIMIT and OFFSET clauses. These two clauses in essence specify a range of results (database rows) to output.

In CodeIgniter, the pagination library takes care of figuring out how many pagination links are required, and inserts the OFFSET clause value as a method argument to the controller method you are calling it from. Here is an example of just one pagination link

<a href="/language/read/20" data-ci-pagination-page="2">2</a>

How to do it

Here is how I attempted to use pagination.

Controller

public function read($pagination_offset = 0)
{
  $this->load->library('pagination');
  $pagination_config['base_url'] = base_url('language/read'); // the controller you are calling
  $pagination_config['per_page'] = 20; // sql query LIMIT number

  $this->data['languages'] = $this->language_model->get_languages($pagination_config['per_page'], $pagination_offset); // your database call with LIMIT and OFFSET arguments
  $total_query_rows = $this->db->query('SELECT id FROM languages')->num_rows(); // what the database would have yielded without the LIMIT and OFFSET clauses (*see Notes)

  $pagination_config['total_rows'] = $total_query_rows;
  $this->pagination->initialize($pagination_config); // prepares the pagination based on your configurations

  $this->data['pagination'] = $this->pagination->create_links(); // outputs the pagination as a string (*see Notes)
  $this->load->view('language', $data);
}

Model

public function get_languages($limit, $pagination_offset)
{
  $query = $this->db->query("
  SELECT
    languages.id AS id,
    languages.title AS language,
    country_code,
    COUNT(courses.id) AS number_of_courses
  FROM languages
  LEFT JOIN courses
  ON languages.id = courses.language_id
  GROUP BY languages.title
  LIMIT $limit OFFSET $pagination_offset
  ");
  return $query->result();
}

Notes

The three most important things here are

  • $pagination_config['base_url'] the controller method to call.
  • $pagination_config['per_page'] the SQL LIMIT or how many results per page you want to see.
  • $pagination_config['total_query_rows'] all the rows in the results set, so the pagination library can figure out how many links to create.

In $total_query_rows instead of writing the whole query without LIMIT and OFFSET, I wrote a much simpler one because I knew it would return the same number of rows every time.

If there is no pagination to show, create_links() will output an empty string.

In the model, you can of course use the query class library to pass LIMIT and OFFSET clauses.

Changing the view output

Above is the minimum you need to get pagination working, but it’s likely you will want to style or customise your output. To do this you can edit the default preferences which are passed to the initialize() function. I prefer to do this by creating a pagination.php file in the config folder. Here is an example using the W3.CSS front-end CSS framework

pagination.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

$config['full_tag_open'] = '<ul class="w3-pagination w3-border w3-light-grey">';
$config['full_tag_close'] = '</ul>';

$config['first_link'] = 'First'; // might require more than 5 pages by default to show up
$config['first_tag_open'] = '<li>';
$config['first_tag_close'] = '</li>';
// $config['first_url'] = ''; // An alternative URL to use for the “first page” link.

$config['last_link'] = 'Last';
$config['last_tag_open'] = '<li>';
$config['last_tag_close'] = '</li>';

$config['next_link'] = '&raquo;';
$config['next_tag_open'] = '<li>';
$config['next_tag_close'] = '</li>';

$config['prev_link'] = '&laquo;';
$config['prev_tag_open'] = '<li>';
$config['prev_tag_close'] = '</li>';

$config['cur_tag_open'] = '<li><b><a class="w3-green">';
$config['cur_tag_close'] = '</a></b></li>';

$config['num_tag_open'] = '<li>';
$config['num_tag_close'] = '</li>';

View

<?php if (!empty($pagination)): ?>
  <div class="w3-container">
    <div class="w3-card-2 w3-padding w3-light-grey">
      <?php echo $pagination; ?>
    </div>
  </div>
<?php endif; ?>

22 December 2016

Creating backups of database rows

I came across a situation where I needed to make a backup of every row either newley insterted, or updated in my database. I didn’t want to share the latest backed up data on the same table, but then needed a way to reference the pk id of the original row when the data from that row was created for the first time.

MySQL has a handy function called LAST_INSERT_ID() which get’s the last inserted row id just executed. CodeIgniter also has a very easy way to get this value $this->db->insert_id();, which can be assigned to a variable and used with an insert statement, to create a reference to the backup of the new row in the backup table. You'll probably also want to do this under a table lock to prevent concurrent operations.

I don’t know whether this is the best way to do backups. This is just something I came up with. I should probably lookup how others do it at some point :P

15 December 2016

My essential web development tools, processes, libraries

This post will be continuously updated/revised.

Visualisation

Charts and graphs: https://gionkunz.github.io/chartist-js/

Charts and graphs: http://www.chartjs.org/

Sortable tables: http://tablesorter.com/docs/

Vertical slides: http://alvarotrigo.com/pagePiling/#page1

Responsive design

Emmet Re:View is a small Google Chrome extension that finds responsive design breakpoints on your page and creates view for each breakpoint.

HTML customisation

tablecloth.js is a jQuery plugin that helps you easily style HTML tables along with some simple customizations.

List.js adds search, sort, filters and flexibility to plain HTML lists, tables, or anything.

HTML5 Mobile

Ionic is a powerful HTML5 native app development framework that helps you build native-feeling mobile apps all with web technologies like HTML, CSS, and Javascript.

Dynamic pages

scrollMonitor allows you to receive events when elements enter or exit a viewport.

ScrollReveal - Easy scroll animations for web and mobile browsers.

Resources

Learn Layout teaches the CSS fundamentals that are used in any website’s layout.

Language libraries

The Voca library offers helpful functions to make string manipulations comfortable

Front-end libraries

W3.CSS is a modern CSS framework with built-in responsiveness. It's based on Google's material design, and is extremely light and easy to work with.

Resolving issues using Google's smtp email with Codeigniter

So this took me days to figure out, so hence a blog-post.

I’ve been looking for an easy way to test apps that use email locally. Using an online smtp service like gmail is in my opinion, much easier than setting up a local mail server. The natural choice for me was gmail since I have already created some test accounts for development there (It’s best not to mix personal and dev accounts for reasons which will be apparent later on). However, I did run into a couple of issues trying this with CodeIgniter.

Issue 1.

With your dev account open, go here and turn on access for less secure apps. Thanks to http://www.wpsitecare.com/gmail-smtp-settings/ for that.

Issue 2.

After loading CodeIgniter’s email library, the following line is essential to send email

$this->email->set_newline("\r\n"); // in the controller

or add the equivalent to the email config file (see example below)

$config['newline'] = "\r\n"; // essential to use double quotes here!!!

(Update: I’ve found more info on that issue here).

After checking off these two points, you can now proceed to send smtp email locally.

Here is a quick example

In application/config, create a file called email.php (it will be automatically recognised by CodeIgniter). Add the following

<?php if(!defined('BASEPATH')) exit('No direct script access allowed');

// SMTP config
$config['mailtype'] = 'html'; // default is text
$config['protocol'] = 'smtp';
$config['charset'] = 'utf-8';
//$config['newline'] = "\r\n"; // essential to use double quotes here!!!
$config['smtp_host'] = 'ssl://smtp.gmail.com';
$config['smtp_port'] = 465;
$config['smtp_user'] = 'your_dev_email@gmail.com';
$config['smtp_pass'] = 'Your_Password';

In your controller, add

$this->load->library('email');
$this->email->set_newline("\r\n"); // will fail without this line!!!

$this->email->from('your_dev_email@gmail.com', 'Your_Name');
$this->email->to('another_dev_email@gmail.com');
$this->email->subject('Email Test');
$this->email->message('Test_mail controller.');

if($this->email->send()){
  $data['message'] = "Mail sent...";
}
else {
    $data['message'] = "Sorry Unable to send email...";
}

$this->load->view('your_view', $data);

Then check the output in your_view by echoing the $message variable, and of course check your email ;)

9 November 2016

Responsive font sizes

When designing for mobile, a lot of things have to move and scale. One of those things are fonts and their size must be adjusted to look good for various screen sizes. One way to do this is with a base measurement in % and the em measurement which is relative to the base measurement.

Let’s see some code…

body {
    font-size: 100%; /* This is the base value */
}

.font-regular {
    font-size: 1em;
}

.font-large {
    font-size: 1.5em;
}
.font-extra-large {
    font-size: 2em; 
}

Now when the base size changes all the font sizes are updated accordingly. You can also use this base for things like margins etc…

Responsive horizontal menu

Here is how I do a simple responsive horizontal menu where the elements are equally spaced.

CSS for four items…

.menu-item {
    width: 24%;
    margin: 0 0.5%;
    float left;
}

Adjust the percentage as required.

6 November 2016

Awesome WordPress plugins

Here is a list of my favourite WordPress plugins.

JavaScript AutoLoader

http://petersplugins.com/free-wordpress-plugins/javascript-autoloader

This Plugin allows you to load additional JavaScript files without the need to change files in the Theme directory. To load additional JavaScript files just put them into a directory named jsautoload.

Clicking the JavaScript AutoLoader question mark icon on the Plugin page will show you the following…

Possible paths to store your JavaScript files

Child Theme Directory

Current Path: /var/www/example.dev/public_html/wp/wp-content/themes/eaterstop-pro-child/jsautoload

Theme Directory

Current Path: /var/www/example.dev/public_html/wp/wp-content/themes/eaterstop-pro/jsautoload

General Directory

Current Path: /var/www/example.dev/public_html/wp/wp-content/jsautoload

To make sure your JS code runs after everything has loaded, run it in the following function

window.onload = function() { 
    // your code here
}

BackUpWordPress

By: http://hmn.md

BackUpWordPress is one of several free solutions available to wordpress owners. It is my preferred one because it has an uncomplicated user interface, and gives you the option to either schedule back-ups of just the database, or everything.

Easy WP SMTP

By: https://wp-ecommerce.net

Easy WP SMTP simply allows you to send email via SMTP from your WordPress Blog. Why would you want to do this? I recently had a client’s hosting provider move to a cloud based platform and remove support for php’s mail (sendmail) function. The plugin allows wordpress to use any smtp mail account (including your hosts email service) to send mail. It also apparently helps keep mail sent from wordpress out of people’s spam folders.

5 September 2016

Step-through Debugging with xdebug for php

Here is how to set up step-through debugging for php on various editors that support it. The install was on Ubnuntu 14.04.

Install by running

sudo apt-get install php5-xdebug

Next, open /etc/php5/apache2/php.ini and add the following (check the specific xdebug folder name)…

This part was giving me a message that "Module 'xdebug' already loaded". Not including the following line seems to have dismissed that message.

zend_extension="/usr/lib/php5/20121212/xdebug.so"

In the same file, find the commented line

; report_zend_debug = 0 

and uncomment it. This line apparently activates the debugging of data, but only with an installed debugger like xdebug.

Finally in php.ini, add the following settings.
Note 1: with these settings, the debugger will connect to your editor for every script it executes.
Note 2: xdebug.remote_connect_back=1 is not safe for production servers according to https://atom.io/packages/php-debug

xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_connect_back=1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_autostart=true

Save up and restart apache for changes to take effect.

sudo service apache2 restart

I had this working in both Atom and Visual Studio Code editors by installing the extension php-debug.