Saturday, April 4, 2009

Solution for content duplication

The content your site publishes are often reachable trough multiple urls. It happened to me while using Horde_Routes (which is really nice way to organize your urls with Seagull), and there weren't easy workarounds (http redirect is not a too nice solution)

This could cause you problems with search engines, because "score" of that particular content are spread trough multiple urls. Your content gets lower relevance in search results which is definitely not what you want.

Now there is a nice solution for this issue called : cannonical URL link

Basically you just have to add
<link rel="canonical" href="http://someurl/comes/here" />

to HEAD section and you are done. It will tell the search engines which url to associate with content. All major search engines support canonical url links.

With Seagull you have to modify www/yourtheme/default/header.html and add a line like

<link flexy:if="canonicalUrl" rel="canonical" href="{canonicalUrl}" />

which means that if you set $output->canonicalUrl in your controller it will find its way to search engines

Monday, March 23, 2009

Mysql spatial extension

I must be the only one around who didnt knew that mysql spatial extension exists... It is a life saver if proximity based search is to be implemented. Without it you would have to calculate lat/lang ranges that are within some distance of base point (was there, you dont want to), which is rather costly operation, not to mention that this stuff allows to tell if points are inside a polygon or whatever, so good to know its out there, wont forget it next time I encounter some google maps/kml related stuff...

Has anyone used it? Performance?

Thursday, October 23, 2008

Remove index.php from urls in Seagull with mod_rewrite

To make Seagulls urls even more SEO friendly, you can "remove" index.php from them. It could be done relatively easily with Apache`s mod_rewrite module.

Example of functionality:

http://www.example.com/index.php/default/maintenance/
=>
http://www.example.com/default/maintenance/

Apache configuration

You need to enable mod_rewrite module first. Then you have to make decision where to keep your rewrite rules. Options are : global httpd.conf, virtualhost or .htaccess files. I dont suggest .htaccess files as apache should check them for every request, and with higher load you dont want it. I keep rules in virtualhost files. Lets see an example:

/etc/apache2/sites-available/www.example.com

<virtualhost *>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/example.com/www
ServerName www.example.com
<Directory /var/www/example.com/www>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L]
</Directory>
# RewriteLog /var/log/apache2/example.com-rewrite

ErrorLog /var/log/apache2/example.com-error_log
CustomLog /var/log/apache2/example.com-access_log common
</virtualhost>

The rewrite rules are set on same directory as document root.

For each request:
- check if the requested url is an existing file
RewriteCond %{REQUEST_FILENAME} !-f

- If its not a file, prepend index.php.
RewriteRule ^(.*)$ index.php/$1 [L]

Save config file & reload apache in order to use newly set up rules

You can test if the rewrite rules function properly by simply typing in few in your browser without index.php.

Seagull configuration

Next step is to change how Seagull generates links because we dont want index.php in our links any more. You have to edit Seagull config file located in <install_dir>/var/www.example.com.conf.php , and set frontScriptName to an empty string:

$conf['site']['frontScriptName'] = '';


You can find out more about this at:
Seagull Wiki

Monday, September 8, 2008

Move made, Ubuntu hardy heron installed

Finally switched from Win XP to Ubuntu, and got around with it. It was a long delayed step because most of my stuff worked nicely with Win Xp, but lets admit other OS`s handle better scripting :) OS install went fine, and the core system was in place really soon. Had some hard times with downloading medibuntu packages, but mostly because of my ISP i guess.

Most of my dev environment up and running, with minor fixes.

ZendStudio for Eclipse produced some nice error message when it was trying to build a Seagull based project but there is a RC of editor (ZendStudioForEclipse-6_0_1_1RC1) that has fixed cause of it.

Have set up apache for my existing vhosts for apache2, mysql. Made Navicat running trough wine along with Safari. Havent had problems with wine, no freezes. But firefox 3 produces really strange behaviours like 100% CPU usage, and show big apetite for memory, could be caused by firebug tho.

What still remains to be done is getting IE browsers running for testing purposes, trough ies4linux . Should install some Photoshop as well, hope that there are no problems with it.

More or less everything is working in order, and can use my existing data from ntfs partitions.

Interested to see how we will get along :)

Tuesday, June 24, 2008

jQuery form plugin data manipulation

jQuery form plugin is a great piece of code, and if you are working with ajax forms its your best friend. The basic usage of it is excellently explained of their site.

It happens from time to time that you have to serialize/create some values into a hidden form field and extract the data on the server side. I came up with a solution to avoid this unnecessary serialization/deserialization.

You can provide your custom code in beforeSubmit callback. It works like this:

beforeSubmit: function(formData, jqForm, options) {
jqForm.find('select[@name=listItems]')
.children()
.each(function(){
formData.push({
name: 'aListItems['+$(this).attr('value')+']',
value: $(this).text()
});
});
}


This code snippet would find a select field named 'listItems' within the posted form and convert all of its options into an array that gets posted to server side (and there easily accessible trough $_POST from PHP).

formData parameter of beforeSubmit callback is an JS array that contains all the fields of the form, and as it is passed by reference you can add your custom fields to it, and form plugin will see them as parts of the form. jqForm parameter is a reference to jQuery ajaxForm object, so you can use it to extract data.

This solution should work for any type of data manipulation before the form submit.

Saturday, June 14, 2008

Moving select options with jQuery

I wanted to move select options up/down on a click of a button. The following jQuery snippet does exactly that, if you want to put in some moveby variable (delta) execute this stuff within a for loop

#UPDATE My implementation was valid ages & jQueries ago, thanks to imants.horsts for updated solution

$.fn.moveSelectedUp = function() {
var selectedOptions = $(this).selectedOptions();
var prev = $(selectedOptions).first().prev();
$(selectedOptions).insertBefore(prev);
}

$.fn.moveSelectedTop = function() {
var selectedOptions = $(this).selectedOptions();
var first = $(this).children("option").not(":selected").first();
$(selectedOptions).insertBefore(first);
}

$.fn.moveSelectedBottom = function() {
var selectedOptions = $(this).selectedOptions();
var last = $(this).children("option").not(":selected").last();
$(selectedOptions).insertAfter(last);
}


This solution is tested in FF3 & IE6/7, should work elsewhere as well

Thursday, June 12, 2008

My Grandmother

My Grandmother (aged 83) today gave me a call. Nothing special, from her mobile phone (she prefers large letters, and better display because she sends SMS`s daily). The interesting thing is the she saw the german army occupying Serbia from her workplace, the time when only few of them had radios and tv sets (with sometimes watchable single demo channel) were a rarity. She called to alert me on a new virus on the Internet?! I wonder about what is left for us to see