WordPress

WPML URL override on archive page

Last week I ran into an issue with WPML URLs on post type archive page. When the permalink is set to %post_name%, we can access the archive page following //site_url/post_type_slug. And the posts can be filtered by taxonomy using //site_url/post_type_slug?taxonomy_name=taxonomy parameter in the URL. With WPML language switcher things become a bit tricky.

The issue

When I tried to change the language on the archive page while the taxonomy filter was present in the URL, WPML tend to take me to the taxonomy archive page instead. Let’s say for example my URL was http://ashiqur.com/books/?genre=fiction and when I tried to change to a different language (e.g. French) the URL became http://ashiqur.com/fr/le-genre/la-fiction while I expected it to be http://ashiqur.com/livres/?le-genre=la-fiction. Here livresla-genre and la-fiction is French translation of booksgenre and fiction respectively.

This wouldn’t be an issue for most cases. But in this particular case, I wanted to display only the detail of each genre along with some other info on their archive page and then show the books of each genre on the books archive page using the URL parameter.

Solution using WPML filter

The filter icl_ls_languages to the rescue! I added this filter to catch the language switcher and modify the URL before sent out to the output. Here is the final code I used:

Inside the foreach loop of languages I checked if this is a post_type_archive using is_post_type_archive() function. We can use is_search(), is_archive() or any similar function based on our need. Used the get_queried_object() function to get the current taxonomy and get_post_type() to fetch current post type. I checked whether $archived_taxonomy->slug is set to make sure we are filtering by a taxonomy and the WPML’s language switcher is going to redirect me to a different URL. So, next step is to generate the right URL and replace the WPML generated one with that.

Now that we have the taxonomy ID, we can get the counterpart of that in other language using wpml_object_id filter. Problem is, when we pass that ID to get_term() function, WPML takes over and adjusts the ID to our active language. So, we’ll get the taxonomy that I already have! Here comes the use of the global variable $icl_adjust_id_url_filter_off. I backed up the existing value of that variable (generally false), set it to true and then called the get_term() function like this:

//Backup the global variable
$orig_flag_value = $icl_adjust_id_url_filter_off;
//Set the global variable to true
$icl_adjust_id_url_filter_off = true;
//Fetch the translated counterpart of the term
$translated_term = get_term( apply_filters( 'wpml_object_id', $archived_taxonomy->term_id, $archived_taxonomy->taxonomy, false, $lang_code ), $archived_taxonomy->taxonomy );
//Reset the global variable to it's old value
$icl_adjust_id_url_filter_off = $orig_flag_value;

Now that I have the translated taxonomy name and slug, I replaced the query string of current URL using the desired taxonomy slugs. Then replaced the language URL to the post type (books in this case) archive page instead of taxonomy archive page and appended the new query string.

That it! Now the taxonomy archive works fine on its own and the post type archive works fine with query strings. %DRUMROLLS%!!

Useful extensions for Laravel

I’m starting to love Laravel. And while starting new project, there are few extensions I like to use which saves a lot of time. Maybe someone else will find these useful as well.

1. Laravel 4 Generators

A really awesome extension from Jeffrey Way. This makes life easier by creating all the controllers and models with a single command. A must have extension before starting a new application.

2. Confide

Every app requires a decent authentication system. To sum up the required features there need to be a registration process, a log in process, email validation, password recovery etc. This is really tedious to create all those over and over. Confide solves that problem.

3. Entrust

This might not be essential for all applications but it is a very useful one too. This extension creates a role management on Laravel. This is from the same author of Confide and works better with it.

I’ll enrich this list later if I get to love some other useful extension. All the related suggestions are welcome.

CodeIgniter template library

The thing I hate most about CodeIgniter is that the views folder become messed up after a while. So many files and so difficult to track down a view for a certain area of an application. So, to solve that I figured I should create a library to override the ways of managing views. I wrote this very small library to solve the problem. Now I can easily create different templates (or themes whatever you prefer them to call) inside the views. Also I’ve added a layout file (or you can call the master file) in the template for the base structure of the page. So, I don’t have to repeat the areas like header, footer or menu on every view. The library can be download the library from GitHub.

Here I’ve explained how the library works and how to integrate it within a CodeIgniter application.

The library

So, the library is simple consisting only three methods – get, set and view. They does exactly what they are called, get current template, set active template and loads the view respectively. Also I’ve defined the default template, which is used in case template is not set anywhere, at the top of the library.

define('DEFAULT_TEMPLATE', 'default');

You can set the default template in the config file if you like. Let’s jump into the library codes.

First the global variables and constructor of the library.

var $ci;
public function __construct() 
{
    $this->ci =& get_instance();
}

I prefer to load the CodeIgniter instance inside the constructor instead of inside every function. Nothing fancy about it. Next is the get function.

public function get($default = DEFAULT_TEMPLATE)
{
    $template = $this->ci->session->userdata('active_template');
    if($template && $template !== NULL) {
        return $template;
    }
    return $default;
}

We assume that the template name is set in the session. But if nothing was found in the session, we use the default value defined at the top of the library.

In the set function, we just set the template name in the session.

public function set($default = DEFAULT_TEMPLATE)
{
    $this->ci->session->set_userdata('active_template', $default);
    return $default;
}

Remember, our session library must be loaded. I prefer to load it using autoload.php as I use the session a lot.

Finally in the view function, I’ve checked for the existence of the desired view within the template and if the file exists I’ve loaded the view within the layout (master file I’ve mentioned earlier) of that template.

public function view($view = '', $data = NULL, $alternate_template = FALSE, $template = DEFAULT_TEMPLATE, $print = FALSE)
{
    $template_name = $template;
    if(!$alternate_template) {
        $template_name = $this->get();
    } 
    if(strlen($view) == 0 || !file_exists( APPPATH . 'views/' . $template_name . '/' . $view . '.php')) {
        show_error('Unable to load the template: ' . $template_name . '/' . $view . '.php');
    }
    if(!$print) {
        $this->ci->load->view($template_name . '/' . 'layout', array('data' => $data, 'view' => $template_name . '/' . $view));
    }
}

Here I’ve used the $print variable to determine whether to load the view or not. Sometimes I want to handle AJAX calls which should not be sent to output.

Adding template

To add a new template we need to add a directory within the views directory. Every directory within the views are considered as a template. Inside each template there should be a layout.php file and all other views you need. You can put your views within sub directories if you want but the layout.php must stay right within the template directory. So, if I add a new template called mytemplate the directory structure will be like this:

|_ viewes
    |_ mytemplate
        |_ layout.php
        |_ otherview.php

The layout file

The structure of layout.php depends on however the application looks like. We just need to use  $this->load->view($view, $data); wherever we want to output our view’s content. So, a sample layout.php file might look like this:

<!doctype html>
<html>
<head>
    <title><?php echo (isset($data['title'])? $data['title'] : "My Website Title") ?></title>
</head>
<body>
    <div class="wrapper">
        <?php $this->load->view($view, $data); ?>
    </div>
</body>
</html>

Usage

Well, using the library is very easy. Once the library is placed inside the applications library folder and loaded in the controller (though I prefer using autoload.php), we can load a view using  $this->template->view('view_name', $data); in the controller. Now, to organize the views properly we can make sub directories within the template. Let’s say we have an index view for the home controller and an account view for member controller. We can create two folder called home and member within the template folder and then add the views like home/index.php and member/account.php files. Then from the index function of home controller we should call the view like:

$this->template->view('home/index', $data);

And from the account function of member controller we should call the view like:

$this->template->view('member/account', $data);

That’s about it. Download the files from the GitHub repository and I’ve added a sample controller with sample template structure in there.

File upload/download on MySQL database

Well… It is already a well discussed topic. But when I was first trying to find out how to do this, I really got stuck. Actully it took me a lot of time to find out the key code segment for the purpose.

So, here is what I’ve learned:

The table:

Suppose the structure of the MySQL table (say ‘file_table‘) is like this:

It has three fileds:

  • id : the primary key, integer type with auto increment feature.
  • content: the content of file, blob type.
  • type: varchar type, the type of the file (e.g. doc, pdf etc.).

Upload:

I think you can create a HTML form with a input with file type. Its pretty simple. Just use this code to make a input field be able to upload file:

<input id="file_upload" name="file_upload" type="file" />

Now the backend coding. I’m using PHP for this. Continue reading

Basic PHP – Part 1

This article is about very basic of PHP coding, creating functions and database connection using PHP. Later posts may contain detail about other features.

Target viewers are assumed as familiar with C/JAVA or other similar programming language. So I didn’t bother to clarify basic syntax.

Writing PHP code:

All your PHP content should be inside <? ?> tags. That is the file format should be:

<?
Your content here.
?>

Most of the functions in PHP are similar to C. So if you can code in C, you can code in PHP. There are simple exceptions as: Continue reading