<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>l'indicible blog &#187; Tutorials</title>
	<atom:link href="http://www.lindicible.com/blog/en/category/tutoriaux/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lindicible.com/blog</link>
	<description>&#60;!--:en--&#62;the details of the inexpressible&#60;!--:--&#62;&#60;!--:fr--&#62;les détails de l'ineffable&#60;!--:--&#62;</description>
	<lastBuildDate>Thu, 01 Jul 2010 14:20:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How to automatically add a trailing slash to an URL</title>
		<link>http://www.lindicible.com/blog/en/2010/05/03/comment-ajouter-automatiquement-un-slash-en-fin-durl/</link>
		<comments>http://www.lindicible.com/blog/en/2010/05/03/comment-ajouter-automatiquement-un-slash-en-fin-durl/#comments</comments>
		<pubDate>Mon, 03 May 2010 20:55:23 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=548</guid>
		<description><![CDATA[After long and boring researchs on how to automatically add a trailing slash ( &#8216;/&#8217; ) after my web sites&#8217; addresses, I thought some people might enjoy sharing the results of this quest&#8230; For those who would wonder the purpose in that, it&#8217;s once again about search engine optimization. Indeed, for a search engine, http://www.webagency.com/name [...]]]></description>
			<content:encoded><![CDATA[<p>After long and boring researchs on how to automatically add a trailing slash ( &#8216;/&#8217; ) after my web sites&#8217; addresses, I thought some people might enjoy sharing the results of this quest&#8230;</p>
<p>For those who would wonder the purpose in that, it&#8217;s once again about search engine optimization.<br />
Indeed, for a search engine, http://www.webagency.com/name and http://www.webagency.com/name/ are not the same. This is inherited from a time where /name would be a file and /name/ a directory. Nothing by then was preventing a file and folder in the same place to share a name.</p>
<p>Today, we took the habit to use more clear and user-friendly URIs, and most of the time we make it so that http://www.webagency.com/name and http://www.webagency.com/name/ point toward the same page.<br />
Once again, the risk is to end up with two pages being considered as dupes by the search engines, diluting the global weight of the page.<br />
To avoid this, we will try to have a canonical page, and to have the other one point onto this one.</p>
<p>There is several ways to so so, the easiest probably being the use of the <a href="http://www.google.com/support/webmasters/bin/answer.py?hl=en&#038;answer=139394" rel="external">&#8220;canonical&#8221; attribute</a> recently introduced by Google.<br />
For reference, it is about using a &lt;link rel=&#8221;canonical&#8221; href=&#8221;http://www.webagency.com/w3c.php?quality=high&#8221;&gt; like tag in the &lt;head&gt; section of the page.<br />
This way, several URLs will be allowed to point to this page, but Google will know that the address given in the href is the one to take into account.</p>
<p>Another method is to always redirect the visitor to the address we want to have as the main one.<br />
This can be done at the page level (for example <a href=http://www.php.net/manual/en/function.header.php" rel="external">with php</a>), but it is probably more fit to do it from the web server (Apache) or a .htaccess file.<br />
We then have several tools at our disposal, related to mod_alias and mod_rewrite (make sur they are activated on your hosting platform before you begin experimenting! This is not always the case)</p>
<p>My experiments lead me from RewriteRule to RedirectMatch, and back to RewriteRule for a result that at last seemed satisfactory.<br />
As a documentation, I suggest you visit Apache&#8217;s doc, particularily the following links :<br />
<a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule" rel="external">http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule</a><br />
<a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog" rel="external">http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritelog</a></p>
<p>With no further ado, here&#8217;s my solution :</p>
<pre>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} (^/blog/.*)$  [NC]
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.+[^/])$  %{REQUEST_URI}/  [R=301,L]

RewriteRule ^.*$ index.php [NC,L]
</pre>
<p>Let&#8217;s take a closer look :</p>
<pre>
RewriteEngine On
</pre>
<p>We make sure the URL rewriting engine is on. If it is not available, we will usually get a 500 error.</p>
<p>We will then test various cases :</p>
<pre>
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_URI} (^/blog/.*)$  [NC]
RewriteRule ^.*$ - [NC,L]
</pre>
<p>If the link points to a non empty file (-s = sized file)<br />
or<br />
the link points to a symbolic link (-l = link)<br />
or<br />
the link points to a directory (-d = directory)<br />
or the URI begins with /blog/ with no regard to case (NC = Not Case-sensitive)<br />
then we will replace the URL with itself (-) and ignore the following rules (L = Last rule)</p>
<pre>
RewriteRule ^.*[^/]$  %{REQUEST_URI}/  [R=301,L]
</pre>
<p>If we are sill here, it means the previous conditions didn&#8217;t apply.<br />
So we are not facing a file/link/directory nor a blog entry (that we put here as an example of a branch to exclude&#8230; Note that blogs like WordPress have their own URL rewriting engine).<br />
We are therefore going to replace everything that doesn&#8217;t finish with a / ( described as ^.*[^/]$ using regular expressions ) with the requested address followed by a / ( %{REQUEST_URI}/ ) and make an external redirection on this address (R = Redirect, 301 = the error code we want to return ).<br />
This will be our last rule (L = Last), in order for it not to be replaced by another one before it gets applied (this seems trivial, but I must have lost some hairs before I realised it!)</p>
<p>At last, within the frame of our customised URLs projects, we will usually send everything else toward index.php that will interpret it :</p>
<pre>
RewriteRule ^.*$ index.php [NC,L]
</pre>
<p>There may be better ways to proceeed. If that is the case, I&#8217;d be glad to find out about them.<br />
Anyhow, feel free to leave a comment, it&#8217;s always appreciated <img src='http://www.lindicible.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2010/05/03/comment-ajouter-automatiquement-un-slash-en-fin-durl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Variable size custom button with CSS</title>
		<link>http://www.lindicible.com/blog/en/2010/02/16/bouton-customise-a-taille-variable-en-css/</link>
		<comments>http://www.lindicible.com/blog/en/2010/02/16/bouton-customise-a-taille-variable-en-css/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 15:41:39 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=495</guid>
		<description><![CDATA[Introduction Recently, I&#8217;ve been looking at what is called &#8220;elastic&#8221; css layout. Basically, il&#8217;t about using the &#8220;em&#8221; unit instead of the pixel. This unit is a relative unit, as the &#8220;%&#8221;, but it is relative to the current font size instead of the container size. To understand its usefulness, one has to know that [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>Recently, I&#8217;ve been looking at what is called &#8220;elastic&#8221; css layout.<br />
Basically, il&#8217;t about using the &#8220;em&#8221; unit instead of the pixel. This unit is a relative unit, as the &#8220;%&#8221;, but it is relative to the current font size instead of the container size.<br />
To understand its usefulness, one has to know that some people with vision problems usually make use of an option in their browser that that allows them to upsize the default font size.<br />
Texts become bigger and more easily readable. Unfortunately, it is quite rare that the visited site has anticipated this change, and usually the whole layout becomes all broken.</p>
<p>Imagine for example that you have decided to put a nice image behind a link to have a good looking button. If the font size is augmented, the text will most probably get out of that image. All of a sudden, the button becomes less of an eye candy.</p>
<p>Looking for a solution to this problem, I ran accross a post on the excellent site positioniseveything.net that offers a solution allowing to apply semi-transparent drop shadows on any image. The post is visible here : <a href="http://www.positioniseverything.net/articles/dropshadows2.html" rel="external">http://www.positioniseverything.net/articles/dropshadows2.html</a></p>
<p>The approach seemed interesting to me, but not flexible enough to my taste. Indeed, it is based on a huge image, hoping the container will never go beyond that size. Not even mentioning the ever growing screen sizes, this method has a cost in terms of bandwidth. Also, it assumes that we are looking for a &#8220;linear&#8221; image border, which is not always the case.</p>
<p>With Flash, there is a way to handle round corners that is called Scale9Grid : we divide a bloc in 9 distinct bits as illustrated in the picture below, and those located in the corners are never resized.<br />
<img src="http://www.lindicible.com/blog/wp-content/_custom/scale9css/grid.gif" alt="scale9grid" /></p>
<p>Based on this method and the positioniseverything technic, I crafted a way to have a custom button that adapts to its content. You can visit the <a href="http://www.lindicible.com/blog/wp-content/_custom/scale9css/" rel="external">interactive cutom scalable button demonstration</a>.<br />
But I hear you getting impatient already, so here is the said technic :</p>
<h3>Image preparation</h3>
<p>We are going to cut out our button as done in the above picture, with one minor difference.<br />
Counter to Flash, CSS2 doesn&#8217;t allow us to stretch images. So we will keep only a 1 pixel width bit for the parts that have to spread horizontally and repeat this bit as many times as necessary.<br />
Idem for the verical parts, keeping only a 1 pixel high bit.<br />
This step is not really necessary, but it allows not to overload the bandwidth with unneeded data.</p>
<h3>The HTML</h3>
<pre>
&lt;div class="tl"&gt;
    &lt;div class="tr"&gt;
        &lt;div class="bl"&gt;
            &lt;div class="br"&gt;
                &lt;div class="t"&gt;
                    &lt;div class="b"&gt;
                        &lt;div class="l"&gt;
                            &lt;div class="r"&gt;
                                &lt;div class="content"&gt;
                                    Place your content here
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>As you can see, an certain quantity of tags that have for only use to help construct the button is needed. This goes against the principle stating that html always should keep its semantic meaning (which is good for search engines), but one doesn&#8217;t make an omelette without breaking any eggs !</p>
<p>The classes represent the image part that will be used. &#8220;l&#8221; for &#8220;left&#8221;, &#8220;b&#8221; for &#8220;bottom&#8221;, &#8220;br&#8221; for &#8220;bottom-right&#8221;, etc.</p>
<h3>The CSS</h3>
<p>Comments are placed directly within the CSS.</p>
<pre>
.tl{
    background:url('tl.gif') no-repeat top left;
    display:inline-block;
}

.ie7root .tl, .ie7root .tl div{ /* ie7 fix : any haslayout trigger can replace this */
    float:left;
}

.tr{
    background:url('tr.gif') no-repeat top right;
}
.bl{
    background:url('bl.gif') no-repeat bottom left;
}
.br{
    background:url('br.gif') no-repeat bottom right;
    padding-right:23px; /* depends on your right images width */
}
.t{
    background:url('t.gif') repeat-x top left;
    margin-left:23px; /* depends on your left images width */
    padding-top:18px; /* depends on your top images height */
}
.b{
    background:url('b.gif') repeat-x bottom left;
    padding-bottom:18px; /* depends on your bottom images height */
}
.l{
    background:url('l.gif') repeat-y top left;
    margin-left:-23px; /* depends on your left images width */
}
.r{
    background:url('r.gif') repeat-y top right;
    margin-left:23px; /* depends on your left images width */
    margin-right:-23px; /* depends on your right images width */
    padding-right:23px; /* depends on your right images width */
}
.content{
    overflow:hidden; /* prevents non breakable content from overflowing */
    vertical-align:bottom; /* fixes a weird bug about a 3pixel gap in the bottom */
    background-color:#28bcd9;
}
</pre>
<h3>Conclusion</h3>
<p>This method works with all tested browsers, including the dreadful IE6 (which it seems might at last go to retirement soon!).<br />
You can use images with transparency in gif or png format (for the browsers that support it), and so create drop shadows or any other type of border for your links or contents.<br />
If the content changes or if the user changes the font size, the button will adapt !</p>
<p>There will probably be more possibilities to do such things with the coming of CSS3 and HTML5. Until then you can now have contents stylized to your liking, that will be nice to the visually impaired too. Enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2010/02/16/bouton-customise-a-taille-variable-en-css/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>DOMDocument and UTF-8, a php charset problem</title>
		<link>http://www.lindicible.com/blog/en/2009/10/18/domdocument-et-utf-8-un-probleme-de-charset-en-php/</link>
		<comments>http://www.lindicible.com/blog/en/2009/10/18/domdocument-et-utf-8-un-probleme-de-charset-en-php/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 23:44:11 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Php]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=481</guid>
		<description><![CDATA[Today we&#8217;ll see how to manipulate DOM elements with php. We&#8217;ll take for example a very useful function which is oddly kind of hard to find : how to add a specific attribute to some HTML elements. This can be useful for example to add a rel=&#8221;nofollow&#8221; attribute to some links to let the search [...]]]></description>
			<content:encoded><![CDATA[<p>Today we&#8217;ll see how to manipulate <a href="http://en.wikipedia.org/wiki/Document_Object_Model" rel="external">DOM</a> elements with php.<br />
We&#8217;ll take for example a very useful function which is oddly kind of hard to find : how to add a specific attribute to some HTML elements.<br />
This can be useful for example to add a rel=&#8221;nofollow&#8221; attribute to some links to let the search engines know they don&#8217;t need to follow them, while leaving those links available for your users.<br />
In an SEO point of view, it can be quite useful as it prevents your PageRank from leaking to all the links on your pages.</p>
<p>To achieve that goal, we&#8217;ll meet some vicious problems. Let&#8217;s start with a ready function, to preserve the time of the smartests among you :</p>
<pre>
function addAttribute($context, $tag, $attribute, $value)
{
	$initialEncoding = mb_detect_encoding($context);
	if( $initialEncoding != 'UTF-8' ){
		$context = utf8_encode($context);
	}

	$doc = new DOMDocument("4.01", "utf-8");

	$contentPrefix = '&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;required meta for utf-8 handling!&lt;/title&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;/head&gt;&lt;body&gt;';
	$contentSuffix = '&lt;/body&gt;&lt;/html&gt;';

	$doc->loadHTML($contentPrefix . $context . $contentSuffix);

	$elements = $doc->getElementsByTagName($tag);

	if(!is_array($value)){
		$value = array($value);
	}

	foreach($elements as $element)
	{

		foreach($value as $currentValue)
		{
			$alreadySet = false;

			if($element->hasAttribute($attribute))
			{

				$attributeCurrentValue = $element->getAttribute($attribute);

				$attributeCurrentValues = explode(' ', $attributeCurrentValue);

				foreach( $attributeCurrentValues as $attributeCurrentValue )
				{
					if($attributeCurrentValue == $currentValue){
						$alreadySet = true;
					}
				}
				if(!$alreadySet){
					$element->setAttribute($attribute, implode(' ', $attributeCurrentValues) . ' ' . $currentValue);
				}
			} else {
				$element->setAttribute($attribute, $currentValue);
			}
		}
	}

	$output = mb_substr($doc->saveHTML(), 236, -16);

	if( $initialEncoding != 'UTF-8' ){
		mb_convert_encoding($output, $initialEncoding, 'UTF-8');
	}

	return $output;
}</pre>
<h3>Explanations</h3>
<pre>
$initialEncoding = mb_detect_encoding($context);
	if( $initialEncoding != 'UTF-8' ){
		$context = utf8_encode($context);
	}</pre>
<p>We start by detecting the encoding format currently used in the given context.<br />
We store it in order to give the feedback in the same format, and we convert it to UTF-8.<br />
Why UTF-8 ? This format as the (huge) advantage to handle all characters, including the accented or special ones from various languages.</p>
<pre>
	$doc = new DOMDocument("4.01", "utf-8");</pre>
<p>Then, we create a new DOM object, to whose constructor we pass two parameters : the version of the document we&#8217;re going to use (typically &#8220;1.0&#8243; for XML and &#8220;4.01&#8243; for HTML), and the charset of this document.</p>
<pre>
	$contentPrefix = '&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;required meta for utf-8 handling!&lt;/title&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;/head&gt;&lt;body&gt;';
	$contentSuffix = '&lt;/body&gt;&lt;/html&gt;';

	$doc->loadHTML($contentPrefix . $context . $contentSuffix);</pre>
<p>Next, we&#8217;re going to add a header to the given context. Indeed, even if we have defined the <em>expected</em> values for the given document, those will be overrideen by the document if these headers aren&#8217;t declared. And I can assure you that when we don&#8217;t know this, it&#8217;s a hair pulling scenario !! It is undoubtfully the most tricky part of the manipulation.<br />
We can then load the content in that DOM object.</p>
<pre>
	if(!is_array($value)){
		$value = array($value);
	}</pre>
<p>This function allows us to add several values to a given attribute. Therefore if the argument passed to the function is a string, we convert it to an array.</p>
<p>I won&#8217;t spend much time ont the actual function, which is quite explicit.<br />
Just note that we preserve the previous values by storing them in an array, and that we check if the attribute value already exists before adding the new value.</p>
<pre>
	$output = mb_substr($doc->saveHTML(), 236, -16);</pre>
<p>We&#8217;ll then save the result, and remove the prefix and suffix we&#8217;ve added with a function handling multibyte characters. Indeed, a classic substr wouldn&#8217;t wotk well with some characters, as we are here using UTF-8 which uses several bytes to store some of them.</p>
<pre>
	if( $initialEncoding != 'UTF-8' ){
		mb_convert_encoding($output, $initialEncoding, 'UTF-8');
	}

	return $output;</pre>
<p>It&#8217;s time to set the result back to its original charset and to return the result.</p>
<p>And&#8230; Voila! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2009/10/18/domdocument-et-utf-8-un-probleme-de-charset-en-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to detect when the mouse leaves the browser&#8217;s viewport in javascript</title>
		<link>http://www.lindicible.com/blog/en/2009/09/29/comment-detecter-quand-la-souris-quitte-la-fenetre-du-navigateur-en-javascript/</link>
		<comments>http://www.lindicible.com/blog/en/2009/09/29/comment-detecter-quand-la-souris-quitte-la-fenetre-du-navigateur-en-javascript/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 15:57:13 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=421</guid>
		<description><![CDATA[Javascript is a very useful language for many things nowadays. Unfortunately, each browser implements it in a different way, and of course they don&#8217;t offer the same way of handling events ! Let&#8217;s take an example : you&#8217;ve just made a div that you can drag at will with the mouse. We click, the dragging [...]]]></description>
			<content:encoded><![CDATA[<p>Javascript is a very useful language for many things nowadays.<br />
Unfortunately, each browser implements it in a different way, and of course they don&#8217;t offer the same way of handling events !</p>
<p>Let&#8217;s take an example : you&#8217;ve just made a div that you can drag at will with the mouse. We click, the dragging begins&#8230; we let go of the mouse button, the dragging stops. But here&#8217;s the thing : if we let go of the mouse button while outside the browser&#8217;s viewport, no event is triggered, and we keep on dragging our div indefinitely !</p>
<p>The best way to prevent that is to stop the dragging as soon as we leave the browser&#8217;s viewport. But : javascript doesn&#8217;t trigger any event in that case. One has to cheat&#8230;</p>
<p>We begin by saying that if we stop hovering the dragged object, we&#8217;ll stop the dragging&#8230;<br />
And we soon realise it&#8217;s not cool at all ! Indeed, the mouse will nearly always go faster that the div and the dragging will stop instantly, except if we move in slow motion.</p>
<p>To prevent that, one can check toward which element the mouse left the div, and only stop the dragging if that element is not within the html tag.<br />
Easy&#8230; in theory. But all browsers don&#8217;t use the same attributes for the event, and of course IE will be causing trouble !</p>
<p>Without any further introduction, here is a bit of jQuery (&#8220;code less do more&#8221;) that will help you a lot to solve that issue :</p>
<pre>
$('div#dragged').bind('mouseleave.dragged',function(e) {
	var ev = e || window.event;
	if(ev.relatedTarget){
		if(ev.relatedTarget == $('html').get(0)){
			stopDrag();
		}
	} else {
	// IE
		if(!ev.toElement){
			stopDrag();
		} else if(ev.toElement.tagName == "HTML"){
			stopDrag();
		}
	}
})</pre>
<h3>Now, the explanations :</h3>
<pre>$('div#dragged').bind('mouseleave.dragged',function(e) {</pre>
<p>We associate a function to the &#8216;mouseleave&#8217; event on the draggable div.<br />
Please note that jQuery allows us to associate a name to that function (here: &#8216;.dragged&#8217;), which is very useful to then handle the events by name, specially in the case where several events of the same type are associated with this object.</p>
<pre>	var ev = e || window.event;</pre>
<p>We get the triggered event. Firefox and the standard compliant browsers will have it as a parameter of the function (here : &#8216;e&#8217;), for Internet Explorer we&#8217;ll have to fetch it from the window.event.<br />
the double pipe (&#8216;||&#8217;) allows us to give to the variable &#8216;ev&#8217; the value of &#8216;e&#8217; if it exists, and the value of &#8216;window.event&#8217; if that&#8217;s not the case.</p>
<pre>	if(ev.relatedTarget){
		if(ev.relatedTarget == $('html').get(0)){
			stopDrag();
		}</pre>
<p>For the standard browsers, the event contains a &#8216;relatedTarget&#8217; property.<br />
If it exists, we are in the case of a standard browser, else we&#8217;re probably dealing with IE.</p>
<p>This property contains the &#8216;html&#8217; element when we leave the browser&#8217;s viewport.<br />
Here we&#8217;ll use a jQuery syntax to compare the content of that property to the html content (&#8216;get(0)&#8217; on the jQuery object) of the &#8216;html&#8217; tag. If they&#8217;re identical, we can stop the dragging.</p>
<pre>	} else {
	// IE</pre>
<p>If the &#8216;relatedTarget&#8217; property doesn&#8217;t exist, we&#8217;re in the case of IE. Two case are then to be taken care of :</p>
<pre>		if(!ev.toElement){
			stopDrag();</pre>
<p>For some versions of IE, the &#8216;toElement&#8217; property of the event is undefined. This is enough information to stop the dragging.</p>
<pre>		} else if(ev.toElement.tagName == "HTML"){
			stopDrag();
		}
	}
})</pre>
<p>For some other versions of IE, the &#8216;toElement&#8217; property exists. We&#8217;ll then have to check that the &#8216;tagName&#8217; property of the &#8216;toElement&#8217; is indeed &#8216;HTML&#8217;. If that&#8217;s the case, we&#8217;ll stop the dragging.</p>
<p>Here it is, I hope this short explanation may help you out, it&#8217;s not always easy to find on the internet the needed resources to do that thing that seems so basic !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2009/09/29/comment-detecter-quand-la-souris-quitte-la-fenetre-du-navigateur-en-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>URL-Rewriting and SEO</title>
		<link>http://www.lindicible.com/blog/en/2008/12/08/re-ecriture-durl-et-seo/</link>
		<comments>http://www.lindicible.com/blog/en/2008/12/08/re-ecriture-durl-et-seo/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 21:39:26 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[ré-écriture d'url]]></category>
		<category><![CDATA[url-rewriting]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=82</guid>
		<description><![CDATA[You&#8217;ve decided to use url-rewriting to have more readable and &#8216;user-friendly&#8217; ones. That is probably a good thing, given the fact that search engines too prefer them this way. But careful, there are some pitfalls to avoid ! Indeed, with this type of configuration, we don&#8217;t make a good distinction between content and directory&#8230; and [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve decided to use url-rewriting to have more readable and &#8216;user-friendly&#8217; ones. That is probably a good thing, given the fact that search engines too prefer them this way. But careful, there are some pitfalls to avoid !</p>
<p>Indeed, with this type of configuration, we don&#8217;t make a good distinction between content and directory&#8230; and neither do robots! Therefore, http://www.mydomain.com/example and http://www.mydomain.com/example/ usually point to the same content, but appear as two different pages by search engines.</p>
<p>We then have a referencing dilution, and duplicates are coming to the party. How horrid !</p>
<p>We already cured a similar problem regarding <a href="http://www.lindicible.com/blog/en/2008/11/23/multiples-noms-de-domaines-et-seo/">multiple domain names</a> in a previous article. The solution here will be of the same kind.</p>
<p>To avoid any duplicate annoyance, you&#8217;ll have to make sure the addresses without a trailing slash (as http://www.mydomain.com/example) point to the same address with a trailing slash (as http://www.mydomain.com/example/) with a 301error (page moved permanently).</p>
<p>To do so, you&#8217;ll proceed as in the following example, using a .htaccess file or modifying the configuration of the web server :</p>
<pre>&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine On
	RewriteBase /
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteCond %{REQUEST_URI} !-d
	RewriteCond %{REQUEST_URI} !(.*)/$
	RewriteRule ^(.*)$ http://www.mondomaine.com/$1/ [L,R=301]
&lt;/IfModule&gt;</pre>
<ul>
<li>The first line states that we&#8217;re gonna use a rewrite rule, and the second that we&#8217;ll use the current directory as root.</li>
<li><em>RewriteCond %{REQUEST_FILENAME} !-f</em> excludes files that really exist from this rule.</li>
<li><em>RewriteCond %{REQUEST_FILENAME} !-d</em> does the same with directories really existing on the site.</li>
<li><em>RewriteCond %{REQUEST_URI} !(.*)/$</em> takes care of excluding URLs already ending with a slash.</li>
<li>Last, <em>RewriteRule ^(.*)$ http://www.mydomain.com/$1/ [L,R=301]</em> adds a trailing slash to URLs thereby selected, returning at the same time the appropriate error code.</li>
</ul>
<p>Note that you have to place those rules before the pre-existing ones to make sure you get the wanted behaviour.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2008/12/08/re-ecriture-durl-et-seo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiples domain names and SEO</title>
		<link>http://www.lindicible.com/blog/en/2008/11/23/multiples-noms-de-domaines-et-seo/</link>
		<comments>http://www.lindicible.com/blog/en/2008/11/23/multiples-noms-de-domaines-et-seo/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 21:24:45 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[301]]></category>
		<category><![CDATA[multiple sites]]></category>
		<category><![CDATA[redirection]]></category>
		<category><![CDATA[sites multiples]]></category>

		<guid isPermaLink="false">http://blog.lindicible.com/?p=60</guid>
		<description><![CDATA[What to do when we have several domain names pointing to the same site to handle best the referencing ? Be it to protect the closest names (ex: mysite.com and my-site.com) or to take advantage of the various TLD (Top Level Domain) (ex: mysite.com and mysite.org), there are good reasons to use several domain names [...]]]></description>
			<content:encoded><![CDATA[<p>What to do when we have several domain names pointing to the same site to handle best the referencing ?</p>
<p>Be it to protect the closest names (ex: mysite.com and my-site.com) or to take advantage of the various <a rel="external" href="http://en.wikipedia.org/wiki/Tld">TLD</a> (Top Level Domain) (ex: mysite.com and mysite.org), there are good reasons to use several domain names for a single site.</p>
<p>If we don&#8217;t pay attention, the search engines that matter (exhaustive list of search engines that matter:Google) can see those sites as duplicates and/or arbitrarily attribute the pages to one domain or another , diluting your results in the <a rel="external" href="http://en.wikipedia.org/wiki/Serp">SERP</a> (Search Engine Result Pages). In any case, the quality of your referencing suffers.</p>
<p>To avoid this problem, we have to choose a main domain name that will be used as a reference. This implies using that name everywhere you may need to write a URL, and also to alter the behaviour of the secondary domains.</p>
<p>We&#8217;ll make the secondary domains return the same content as the main domain, while warning the robots they&#8217;re not on the main domain. Once again, the <a rel="external" href="http://www.google.com/support/webmasters/bin/answer.py?answer=40132&#038;hl=en">HTTP error codes</a> will get useful : we will return a 301 code (moved permanently) along with the content.</p>
<p>Note that a 302 error code (moved temporarily) would be way less efficient about what we&#8217;re trying to achieve&#8230; and that&#8217;s the one that gets sent by default when a redirection occurs !</p>
<p>To return that code, several methods exist. The simplest is probably the use of the &#8216;redirect&#8217; instruction in the web server (Apache) configuration or in a .htaccess file at the server root.</p>
<p>Here is the instruction to use to redirect all requests to the main address :</p>
<pre>Redirect 301 / http://mysite.com/</pre>
<p>or</p>
<pre>Redirect permanent / http://mysite.com/</pre>
<p>You could for example include a virtual hostname for every secondary domain this way :</p>
<pre>&lt;VirtualHost *:80&gt;
    ServerName www.mysite.org
    ServerAlias mysite.org
    ServerAlias www.my-site.com
    ServerAlias my-site.com
    &lt;IfModule mod_alias.c&gt;
        Redirect permanent / http://www.my-main-site.com/
    &lt;/IfModule&gt;
&lt;/VirtualHost&gt;</pre>
<p>Another way of achieving this without altering Apache&#8217;s conf would be to apply RewriteRules through a .htaccess file at the root of your site. For example :</p>
<pre>RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.*)my-site.com$
RewriteRule ^(.*)$ http://www.my-main-site.com/$1 [R=301,L]</pre>
<p>or with :</p>
<pre>RedirectMatch 301 /blog(.*) /$1</pre>
<p>With a well handled error code, you make sure the main domain achieves all its potential. The search engines that matter are happy, so are you !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2008/11/23/multiples-noms-de-domaines-et-seo/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>404 and SEO</title>
		<link>http://www.lindicible.com/blog/en/2008/10/29/404-et-seo/</link>
		<comments>http://www.lindicible.com/blog/en/2008/10/29/404-et-seo/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 20:02:17 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[codes d'erreur]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=9</guid>
		<description><![CDATA[When trying to optimize a site for a better referencement on search engines, one quickly dives into the underground world of SEO (Search Engine Optimization). There is in that world a lot of common sense and a few tricks to know, along with some concepts flirting with the sacred, like the well known Google&#8217;s PageRank. [...]]]></description>
			<content:encoded><![CDATA[<p>When trying to optimize a site for a better referencement on search engines, one quickly dives into the underground world of SEO (<a rel="external" href="http://en.wikipedia.org/wiki/Search_engine_optimization">Search Engine Optimization</a>).</p>
<p>There is in that world a lot of common sense and a few tricks to know, along with some concepts flirting with the sacred, like the well known Google&#8217;s PageRank.</p>
<p>Globally, you have to understand how the robots used by search engines see your site, i.e. exclusively in text. You can have a glance at what it&#8217;d look like in  a text browser like <a rel="external" href="http://home.pacific.net.sg/~kennethkwok/lynx/">lynx</a>.</p>
<p>Anything that can help those robots work is an advantage for you. Using <a rel="external" href="http://validator.w3.org">w3c</a> validated html and valid stylesheets won&#8217;t change your pagerank, but will give a better visibility of the structure of your site to the robots than formatting it with tables and divs everywhere.</p>
<p>The html code semantics allows robots to distinguish the content types, and use them in a pertinent way.</p>
<p>For example, the &lt;h1&gt; tag should containt first level titles, &lt;h2&gt; tag second level titles, &lt;p&gt; text paragraphs, and so on.</p>
<p>The most important is obviously the &lt;title&gt; tag of your pages, which has to contain the most important keywords as much as possible.</p>
<p>The specificity of robots versus users doesn&#8217;t stop here.</p>
<p>Along with the pages content, error codes are emitted. Those codes rarely are visible to the user, except the famous 404 (page not found), but they are important.</p>
<p>As a reference, here is a <a rel="external" href="http://www.google.com/support/webmasters/bin/answer.py?answer=40132&#038;hl=en">list of error codes</a> a web server might return.</p>
<p>Let&#8217;s imagine you have a dynamic content&#8230; Some pages can disappear from your sites, although some external links still point toward them.</p>
<p>Typically, we want to redirect the user to a page close to his request, rather than confront him with an error page that may stall him. But we also want to warn the search engines that this link is obsolete and has to be removed. Keep in mind that when a robot crosses path with a 404 too often, it doesn&#8217;t like it and that can have consequences on your referencement !</p>
<p>How to solve that, will you ask ? Simply, by emitting an appropriate error code, while displaying content for the user !</p>
<p>The 404 code is the most known, but this error only states that the page could not be reached, for whatever reason. For a page purposefully deactivated, we will prefer the 410 error that states that the page is not available anymore purposefully and not because of a technical problem.</p>
<p>The choice is yours on which <a rel="external" href="http://webmaster.iu.edu/tool_guide_info/errorcodes.shtml">error code</a> seems to fit the page status the more accurately&#8230;</p>
<p>In order to generate an error code, you will need to change the &#8216;header&#8217; of the page. Using php, this means using the following command :</p>
<pre>header('HTTP/1.0 410 Gone');</pre>
<p>Note that the header is the very first thing being emitted when the page is sent. Therefore, it has to be located at the very beginning of the document, before even the doctype declaration(<a rel="external" href="http://en.wikipedia.org/wiki/Document_Type_Definition">DTD</a>).</p>
<p>Not very handy when the content handling system is structured in such a way that it separates the static elements of the page (like the logo or menu) from the actual content. Indeed, if the script sends the top of the page before handling the content related query and noticing it doesn&#8217;t exist, it&#8217;s too late to change the header !</p>
<p>A simple way around this problem is to raise the size of the php buffer.</p>
<p>In php.ini, change the output_buffering line this way:</p>
<pre>output_buffering = 65535</pre>
<p>This value is a limit, but usually enough (if your page don&#8217;t weight an undecent amount!)</p>
<p>You can now return any kind of error when you want, without disturbing your user&#8217;s visit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2008/10/29/404-et-seo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Préchargement d&#8217;images avec jQuery</title>
		<link>http://www.lindicible.com/blog/en/2008/05/23/prechargement-dimages-avec-jquery/</link>
		<comments>http://www.lindicible.com/blog/en/2008/05/23/prechargement-dimages-avec-jquery/#comments</comments>
		<pubDate>Fri, 23 May 2008 19:54:01 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[préchargement]]></category>
		<category><![CDATA[preload]]></category>
		<category><![CDATA[preloading]]></category>

		<guid isPermaLink="false">http://www.lindicible.com/blog/en/?p=5</guid>
		<description><![CDATA[Sorry, this entry is only available in Français.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://www.lindicible.com/blog/category/tutoriaux/feed/">Français</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindicible.com/blog/en/2008/05/23/prechargement-dimages-avec-jquery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
