CakePHP – Simple Custom SEO Friendly URLs w/ Inflector::slug

June 1st, 2011

I was recently presented the problem of creating SEO friendly (and human friendly!) urls for a project.

And as a side note, a lot of other Route details can be attained from the CakePHP 1.3 Manual Routes section.

Let’s not waste any time!

You’re link is going to look like this. NOTE: I am generating a list of links (as the below) with a foreach() thus I can read the record data into my ‘id’ and ‘slug’ below to pass.

1
2
3
4
5
// view.ctp
echo $link->link($planDetailsByCompany['PlanDetail']['name'],
array('controller' => 'plan_details', 'action' => 'view_benefit_schedule',
'id' => $planDetailsByCompany['PlanDetail']['id'],
'slug' =>  Inflector::slug($planDetailsByCompany['PlanDetail']['name'])));

It’s VERY important to note I am using a custom link Helper here ($link->link), but you can use standard CakePHP link Helper just the same. So copying my code will not work “out-of-the-box” for you. But your standard CakePHP link helper will work just fine.

The other critical parts about this are the ‘id’ and ‘slug’ items tacked onto my array(). ‘id’ simply grabs the id and ‘slug’ grabs the name.

Note I am using the Inflector::slug(). This comes in big time handy to properly handle spaces in my url.. Without the this, my URL would typically look like this:

..pd/44-Primary%20Indemnity and with the Inflector::slug() in action, like this: ..pd/44-Primary-Indemnity. Oh yeah much nicer eh?

1
2
3
4
5
// routes.php
Router::connect('/pd/:id-:slug',
array('controller' => 'plan_details', 'action' => 'view_benefit_schedule'),
array('pass' => array('id', 'slug'),
'id' => '[0-9]+'));

As you can see the ‘pass’ array item info gets passed to my URL (from the link helper in my earlier code) to replace the standard URL path arguments. In other words, this Route is overwriting my URL to present it the way I want it: /pd/:id-:slug is the new format I want, so ‘id’ and ‘slug’ are replaced with the passed a parameters from the link Helper:

1
2
...'id' => $planDetailsByCompany['PlanDetail']['id'],
'slug' =>  Inflector::slug($planDetailsByCompany['PlanDetail']['name']...

Hope this helps!

That’s really all there is to this.
 

 

Domain Registry of America – Domain Name Expiration Notice

May 27th, 2011

Dear Friends,

This is pretty old news, but if you are a web site owner, you have probably received a letter like the below.

This means that they know your domain name will be expiring soon, and it kind of makes it look like you need to fill out this form to keep your domain name! They are trying to get you to switch to them as your domain name carrier.

Normally, your domain name will be hosted at GoDaddy, or Enom, or 1 and 1, etc.. Or another major domain name registrar. ALWAYS know your domain name carrier and verify it’s registered through them!

The prices this company offers are MUCH more expensive than most any hosting company as well. Most companies charge $11-$20 a year per domain name – that’s more or less the norm. But this company charges around $30.00 a year!

Anyhow. I thought this might be of interest to you in case this arrives in your mailbox one day.

If you want to join them, go right ahead! They might have really good service and be very helpful as a registrar, but don’t be confused and understand where your domain name is hosted and how you can safely manage it.

CakePHP Simple SEO Friendly URL Solution

May 25th, 2011

If you are trying to do a simple “rewrite” of your url with CakePHP, this solution might help you. Keep in mind, this is by far the simplest way to do this, and the flexibility of this method is on the weaker side.

If you want to manipulate your URL w/ complex regex or other similar methods, study up on this.

But for a simple “fix”, you can make use of the CakePHP native Inflector method.

Consider this:

1
2
3
4
5
6
    echo $html->link($companyName['Company']['short_name'],
        array(
        'controller' => 'plan_details',
        'action'     => 'view_plan_details_list',
        $companyName['PlanDetail']['id'],
        Inflector::slug($companyName['Company']['name'])));

You will see this is a standard URL setup with the exception of the Inflector::slug($companyName['Company']['name']) after the id is called.

Example:

From:

http://domainname.com/plan_details/view_plan_details_list/42/

To:

http://domainname.com/plan_details/view_plan_details_list/42/Nationwide_Mutual_Insurance_Company

As you can see the $companyName['Company']['name'] is tagged onto the end of the URL.

And there you go. A VERY simple URL friendly CakePHP link solution.

CakePHP Fatal error: Allowed memory size of NNNNNNN bytes exhausted (tried to allocate 2873212 bytes) in …

May 23rd, 2011

I would often move my CakePHP development to a live server and find unstoppable Memory limit. Usually a message like this:

1
2
3
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to
allocate 2873212 bytes) in C:\workspace\cake\libs\cache
\file.php on line 138

My solution will not work in all cases, but its apparent the php ini settings are not sufficient to support the amount of memory needed to run the request.

In most of my cases, I was able to modify the .htaccess in the site index directory by adding:

1
php_value memory_limit 64M

below the mod_rewrite call.

This solved my problem.

Ajax & Prototype image loader on $ajax->submit() w/ CakePHP 1.3

May 19th, 2011

I recently had to implement an ajax loader on a search results page. And I documented my working solution.

The controller or AppsController must include the correct Helpers and RequestHandler component to process the Ajax request:

1
2
var $helpers = array('Js' = array('prototype', 'scriptaculous', 'jquery'), 'Ajax', 'Html', 'Form', 'Javascript');
var $components = array('RequestHandler');

The search() function is used to render() (load) the search_index.ctp page. This page includes my search form. You can also see I am using the default layout template in the second argument of render().

1
2
3
function search() {
$this->render('search_index', 'default');
}

This function renders the search results. You will see further below that the form submit action directs to this function:

1
2
3
function search_action_ajax() {
$this->render('search_action_ajax', 'ajax');
}

This template file displays my form and the submit button (below) which you can see is loaded with properties. The most important to note is the “update” which populates the div that is assigned to it; in this case ajax_div. The loading and success calls update the image with the matching element id. This is the actual loader.

1
2
3
4
5
6
7
8
9
echo $ajax->submit('Submit', array('url' => array('controller' => 'plans', 'action' => 'search_action_ajax'),   'update' => 'ajax_div',
'update'  => 'ajax_search_div',
'label'  => 'Get Quotes',
'id'  => 'submitButton',
'evalScripts' => true,
'before' => 'Event.observe(\'ajaxSubmitForm\', \'submit\', clearOnClick());',
'loading' => 'Element.show(\'busy-indicator\')',
'success' => 'Element.hide(\'busy-indicator\')'
));
1
echo $this->Html->image('indicator.gif', array('id' => 'busy-indicator', 'style' => 'display: none;'));

And then of course you need to create the rendered search_action_ajax.ctp, so you can display your results to the view.

Let me know if you have any questions! Hope this was helpful.