Adding Search Engine Optimisation To Your Online Marketing Mix

May 4th, 2011

Search engine optimization is a cost effective way to drive organic traffic to your website, and as web users conduct billions of searches every single day using sites like Google and Yahoo, it is clear that SEO should be considered a part of every website’s online marketing mix. The best marketers know that diversification is key to success so combining search engine optimization with paid linking and PPC can provide a stable basis of traffic and should your search rankings drop you will have other advertising to pick up some of the slack.

Search Engine Optimization

The use of the most suitable keywords and ongoing link building efforts can help to drive literally thousands of visitors to your website every single day. While some of the more competitive keywords will take months to start performing and generating traffic, niche and long tail keywords can deliver results in a matter of weeks as long as you approach your search engine optimisation properly.

Pay Per Click Marketing

During the early days of your SEO campaign, while you are still developing traffic and identifying link sources, you can use paid marketing techniques to pick up the slack. PPC, or Pay Per Click advertising, for example can deliver traffic to web pages instantly. Register with a PPC UK network, write your ad, place your bids, and watch your ads appear on relevant websites.

Other Forms Of Paid Marketing

You can also use banner advertising, affiliate advertising, paid links, paid reviews, and other paid marketing techniques too. All of these techniques offer varying degrees of success to different websites. While some pages will benefit from banner advertising others will not and while one site may generate a lot of interest through paid reviews, other sites may not carry the right type of product to enjoy success down this marketing avenue.

Continued Marketing

Once your search engine optimization efforts begin to bear fruit you can begin to wind down your paid marketing efforts, although if any are showing great success and a positive Return on Investment then you should seriously consider keeping them going.

Search Engine Optimization

Search engine optimization is generally considered a long term method for generating website seo traffic but that doesn’t necessarily mean you have to wait years to start reaping the rewards. Start early in the life cycle of your website, create good quality and well optimized page content, and start building beneficial and relevant links and you’ll soon start to see your organic search engine traffic levels rise.

MySQL Cross-Platform Table Naming

January 27th, 2011

The upper, lower, or camel-casing of MySQL table names is rarely something developers consider. Unfortunately, it can cause major headaches if you are intending to port your application from a Windows or Mac development environment to a Linux or Unix-based host.

Table Name Case Sensitivity

Each table in a MySQL database corresponds to a physical .frm file within the database folder. Therefore, the case sensitivity of your tables relies on the underlying Operating System. For example, assume we have created the following table and filled it with data:

CREATE MyTable (
id SMALLINT unsigned NOT NULL,
name VARCHAR(50)
)

We then run the following query in our code:

SELECT id, name FROM mytable WHERE id = 1;

This query will work correctly on a Windows or Mac host. Unfortunately, it will fail once your application is copied to Linux or Unix.

Note that database, table, and trigger names are affected by case sensitivity. Columns, indexes, stored procedures, event names and aliases are not case-sensitive.

lower_case_table_names

lower_case_table_names is a MySQL system variable which controls how the database resolves table name casing. It can be passed as a start-up parameter for mysqld or within my.ini (although this is known to cause earlier versions of MySQL to fail). The value can be set to:

0 (Linux/Unix default)
Table name comparisons are case sensitive. Tables are stored on disk using the letter case specified.

1 (Windows default)
Table name comparisons are not case sensitive. MySQL converts all table names to lowercase on storage and lookup.

2 (Mac default)
Table name comparisons are not case sensitive. MyISAM tables are stored on disk using the letter case specified, but MySQL converts them to lowercase on lookup. InnoDB tables are stored in lowercase.

It is therefore tempting to set lower_case_table_names to zero on your system. However, Windows users should not do that. The manual warns that if you set lower-case-table-names=0 on a case-insensitive file system and access MyISAM table names using different letter cases, index corruption may result. Nasty.

Recommendations

Personally, I prefer to use lowercase naming conventions for all databases, tables, indexes, keys and other MySQL names. That appears to be the easiest solution.

Speed Up Your Website With PHP Buffer Flushing

January 24th, 2011

PHP output buffering is normally enabled by default. In older versions of PHP, a string would be sent to your browser every time the interpreter encountered an echo statement or text outside the PHP delimiters.

Output buffering makes this process quicker and more efficient. The buffer is essentially a big memory-resident string. When text is output, it’s appended to the buffer rather than returned to the browser immediately. The buffer is then “flushed”, i.e. its contents are transmitted and the string is reset pending further output. Flushing occurs when:

1. the PHP interpreter reaches the end of the page
2. the buffer exceeds the number of bytes specified within PHP’s output_buffering configuration setting, or
3. the flush() or ob_flush() functions are called.

There are a few caveats but, assuming it works within your environment, you should consider flushing the buffer immediately after the page’s tag, e.g.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<BODY>
This page is loading.<br />
<?php flush(); sleep(2); ?>
Almost there…<br />
<?php flush(); sleep(2); ?>
Done.<br />
</BODY>
</HTML>

(If you’re using WordPress, you could use similar code in your theme’s header.php file.)

Once the browser has received the HTML head, it can begin to download all linked CSS files, favicons and other resources. These downloads can occur while the browser is idle and waiting for the main body content.

The speed increase will depend on the server-side processing required, the weight of your page, the quantity and size of your CSS files, and whether the browser has cached any resources. However, it’s such a simple optimization, there’s little reason not to do it.

I’d be interested to know whether this technique results in a perceivable speed difference on your website or application.

32 Tips To Speed Up Your MySQL Queries

January 18th, 2011

If you are interested in how to create fast MySQL queries, this article is for you

  1. Use persistent connections to the database to avoid connection overhead.
  2. Check all tables have PRIMARY KEYs on columns with high cardinality (many rows match the key value). Well,`gender` column has low cardinality (selectivity), unique user id column has high one and is a good candidate to become a primary key.
  3. All references between different tables should usually be done with indices (which also means they must have identical data types so that joins based on the corresponding columns will be faster). Also check that fields that you often need to search in (appear frequently in WHERE, ORDER BY or GROUP BY clauses) have indices, but don’t add too many: the worst thing you can do is to add an index on every column of a table (I haven’t seen a table with more than 5 indices for a table, even 20-30 columns big). If you never refer to a column in comparisons, there’s no need to index it.
  4. Using simpler permissions when you issue GRANT statements enables MySQL to reduce permission-checking overhead when clients execute statements.
  5. Use less RAM per row by declaring columns only as large as they need to be to hold the values stored in them.
  6. Use leftmost index prefix — in MySQL you can define index on several columns so that left part of that index can be used a separate one so that you need less indices.
  7. When your index consists of many columns, why not to create a hash column which is short, reasonably unique, and indexed? Then your query will look like:
  8. Consider running ANALYZE TABLE (or myisamchk –analyze from command line) on a table after it has been loaded with data to help MySQL better optimize queries.
  9. Use CHAR type when possible (instead of VARCHAR, BLOB or TEXT) — when values of a column have constant length: MD5-hash (32 symbols), ICAO or IATA airport code (4 and 3 symbols), BIC bank code (3 symbols), etc. Data in CHAR columns can be found faster rather than in variable length data types columns.
  10. Don’t split a table if you just have too many columns. In accessing a row, the biggest performance hit is the disk seek needed to find the first byte of the row.
  11. A column must be declared as NOT NULL if it really is — thus you speed up table traversing a bit.
  12. If you usually retrieve rows in the same order like expr1, expr2, …, make ALTER TABLE … ORDER BY expr1, expr2, … to optimize the table.
  13. Don’t use PHP loop to fetch rows from database one by one just because you can — use IN instead, e.g.
  14. Use column default value, and insert only those values that differs from the default. This reduces the query parsing time.
  15. Use INSERT DELAYED or INSERT LOW_PRIORITY (for MyISAM) to write to your change log table. Also, if it’s MyISAM, you can add DELAY_KEY_WRITE=1 option — this makes index updates faster because they are not flushed to disk until the table is closed.
  16. Think of storing users sessions data (or any other non-critical data) in MEMORY table — it’s very fast.
  17. For your web application, images and other binary assets should normally be stored as files. That is, store only a reference to the file rather than the file itself in the database.
  18. If you have to store big amounts of textual data, consider using BLOB column to contain compressed data (MySQL’s COMPRESS() seems to be slow, so gzipping at PHP side may help) and decompressing the contents at application server side. Anyway, it must be benchmarked.
  19. If you often need to calculate COUNT or SUM based on information from a lot of rows (articles rating, poll votes, user registrations count, etc.), it makes sense to create a separate table and update the counter in real time, which is much faster. If you need to collect statistics from huge log tables, take advantage of using a summary table instead of scanning the entire log table every time.
  20. Don’t use REPLACE (which is DELETE+INSERT and wastes ids): use INSERT … ON DUPLICATE KEY UPDATE instead (i.e. it’s INSERT + UPDATE if conflict takes place). The same technique can be used when you need first make a SELECT to find out if data is already in database, and then run either INSERT or UPDATE. Why to choose yourself — rely on database side.
  21. Tune MySQL caching: allocate enough memory for the buffer (e.g. SET GLOBAL query_cache_size = 1000000) and define query_cache_min_res_unit depending on average query resultset size.
  22. Divide complex queries into several simpler ones — they have more chances to be cached, so will be quicker.
  23. Group several similar INSERTs in one long INSERT with multiple VALUES lists to insert several rows at a time: quiry will be quicker due to fact that connection + sending + parsing a query takes 5-7 times of actual data insertion (depending on row size). If that is not possible, use START TRANSACTION and COMMIT, if your database is InnoDB, otherwise use LOCK TABLES — this benefits performance because the index buffer is flushed to disk only once, after all INSERT statements have completed; in this case unlock your tables each 1000 rows or so to allow other threads access to the table.
  24. When loading a table from a text file, use LOAD DATA INFILE (or my tool for that), it’s 20-100 times faster.
  25. Log slow queries on your dev/beta environment and investigate them. This way you can catch queries which execution time is high, those that don’t use indexes, and also — slow administrative statements (like OPTIMIZE TABLE and ANALYZE TABLE)
  26. Tune your database server parameters: for example, increase buffers size.
  27. If you have lots of DELETEs in your application, or updates of dynamic format rows (if you have VARCHAR, BLOB or TEXT column, the row has dynamic format) of your MyISAM table to a longer total length (which may split the row), schedule running OPTIMIZE TABLE query every weekend by crond. Thus you make the defragmentation, which means more speed of queries. If you don’t use replication, add LOCAL keyword to make it faster.
  28. Don’t use ORDER BY RAND() to fetch several random rows. Fetch 10-20 entries (last by time added or ID) and make array_random() on PHP side. There are also other solutions.
  29. Consider avoiding using of HAVING clause — it’s rather slow.
  30. In most cases, a DISTINCT clause can be considered as a special case of GROUP BY; so the optimizations applicable to GROUP BY queries can be also applied to queries with a DISTINCT clause. Also, if you use DISTINCT, try to use LIMIT (MySQL stops as soon as it finds row_count unique rows) and avoid ORDER BY (it requires a temporary table in many cases).
  31. When I read “Building scalable web sites”, I found that it worth sometimes to de-normalise some tables (Flickr does this), i.e. duplicate some data in several tables to avoid JOINs which are expensive. You can support data integrity with foreign keys or triggers.
  32. If you want to test a specific MySQL function or expression, use BENCHMARK function to do that.

How to fix xhtml and css validation errors in Virtuemart

November 16th, 2010

There are essentially two issues causing the xhtml & css not to validate.

How to fix the css validation

The css validation error is due to the use of text-align:top in the “Featured Products” block on the shop landing page. The issue being that “top” is not a valid option for the text-align property. Valid options for text-align are:

  • left
  • center
  • right
  • justify
  • inherit

The correct usage to set the vertical alignment is… yup, you guessed it “vertical-align“.

(Read more about the differences between css vertical-align property and css text-align property)

The file that needs to be updated in Virtuemart is located in:
[site-root] > components > com_virtuemart > themes > default > templates > common > featuredProducts.tpl.php

Line 15, change from this:

<div style="float:left;width:<?php echo $cellwidth ?>%;text-align:top;padding:0px;" >

To this:

<div style="float:left;width:<?php echo $cellwidth ?>%;vertical-align:top;padding:0;" >

How to fix the xhtml validation

The second problem causing the xhtml validation to fail was also in the Featured Products file. This time caused by the product title h4, a block level element, being wrapped by a link, which is an inline element.

This can be fixed in two ways:

The first is to reverse the nesting, so the link is inside of the heading.

Line 16, change from this:
<a title="<?php echo $featured["product_name"] ?>" href="<?php $sess->purl(URL."index.php?option=com_virtuemart&amp;page=shop.product_details&amp;flypage=".$featured["flypage"]."&amp;product_id=".$featured["product_id"]) ?>">
To this:
<h4><a title="<?php echo $featured["product_name"] ?>" href="<?php $sess->purl(URL."index.php?option=com_virtuemart&amp;page=shop.product_details&amp;flypage=".$featured["flypage"]."&amp;product_id=".$featured["product_id"]) ?>">

The second option is to change the product title from an h4 to an inline element, such as a span. I personally prefer the first method, as using a heading brings more structure to the page.

How to fix the final xhtml validation errors

The last few xhtml validation errors we caused by the use of ampersands (ie, &) in the stores categories, for example Laptops & Accessories. I tried using the full entity code (ie, &amp;) but the error prevailed.

The quick and easy fix was to simply use the full word ‘and’ instead. This isn’t the most ideal fix, but it works. A better solution would be to add a simple string replace function to replace all instances of & with the full entity code, like Joomla! does with its menus.

Hope this comes in handy in your next Virtuemart project!

You c an find original post here : http://www.prothemer.com/blog/tips-and-tricks/virtuemart-xhtml-css-validation-errors/

[Virtuemart] Customize Order List – adding extra column

November 16th, 2010

In this post, I am going explain on how to add an extra column in Virtuemart Administrator Order List page.

(Note that, in this example, I’m going to add a new address_1 column).

Note: Please refer to my previous post on “adding search keywords” for the SQL query code for the other fields that you want.

Getting Started.

In /administrator/components/com_virtuemart/html/order.order_list.php

locate this section, around line 27. Then add “address_1″ into the line, as below.

//$list .= "first_name, last_name FROM #__{vm}_orders, #__{vm}_order_user_info WHERE ";
// This is the modified line.
$list .= "first_name, last_name, address_1 FROM #__{vm}_orders, #__{vm}_order_user_info WHERE ";

After that, locate this section, as usual and note that “Address_1″ is already the added column.

$columns = Array( "#" => "width=\"20\"",
"<input type=\"checkbox\" name=\"toggle\" value=\"\" onclick=\"checkAll(".$checklimit.")\" />" => "width=\"20\"",
$VM_LANG->_('PHPSHOP_ORDER_LIST_ID') => '',
$VM_LANG->_('PHPSHOP_ORDER_PRINT_NAME') => '',
// This is you "address_1" column header,
'Address_1' => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_PRINT_LABEL') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_TRACK') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_VOID_LABEL') => '',
$VM_LANG->_('PHPSHOP_CHECK_OUT_THANK_YOU_PRINT_VIEW') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_CDATE') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_MDATE') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_STATUS') => '',
$VM_LANG->_('PHPSHOP_UPDATE') => '',
$VM_LANG->_('PHPSHOP_ORDER_LIST_TOTAL') => '',
$VM_LANG->_('E_REMOVE') => "width=\"5%\""
);
$listObj->writeTableHeader( $columns );

As you can see, those are the column headers for the table, and the last line is the function to print out all the column headers.

Then, you will need to locate this section of code, and add $db->f(‘address_1′); as below:

$tmp_cell = $db->f('first_name').' '.$db->f('last_name');
if( $perm->check('admin') && defined('_VM_IS_BACKEND')) {
$url = $_SERVER['PHP_SELF']."?page=admin.user_form&amp;user_id=". $db->f("user_id");
$tmp_cell = '<a href="'.$sess->url( $url ).'">'.$tmp_cell.'</a>';
}
$listObj->addCell( $tmp_cell );
// This will print "address_1" column, which is placed afer the "Name" column
$tmp_cell = $db->f('address_1');
$listObj->addCell( $tmp_cell );

Note: The ordering of the the print cell function (i.e. the $listObj->addCell( $tmp_cell ); ) is important, as you wouldn’t want to jumble up the different fields.Thats all.

Hope this help :)

You can find the original post here : http://blog.gbinghan.com/2010/10/virtuemart-customize-order-list-adding.html

Loading external content with Ajax using jQuery and YQL

November 15th, 2010

Ajax with jQuery is very easy to do – like most solutions it is a few lines:

$(document).ready(function(){
$('.ajaxtrigger').click(function(){
$('#target').load('ajaxcontent.html');
});
});

Check out this simple and obtrusive Ajax demo to see what it does.

This will turn all elements with the class of ajaxtrigger into triggers to load “ajaxcontent.html” and display its contents in the element with the ID target.

This is terrible, as it most of the time means that people will use pointless links like <a href="#">click me</a>, but this is not the problem for today. I am working on a larger article with all the goodies about Ajax usability and accessibility.

However, to make this more re-usable we could do the following:

$(document).ready(function(){
$('.ajaxtrigger').click(function(){
$('#target').load($(this).attr('href'));
return false;
});
});

You can then use <a href="ajaxcontent.html">load some content</a> to load the content and you make the whole thing re-usable.

Check out this more reusable Ajax demo to see what it does.

The issue I wanted to find a nice solution for is the one that happens when you click on the second link in the demo: loading external files fails as Ajax doesn’t allow for cross-domain loading of content. This means that <a href="http://icant.co.uk/">see my portfolio</a> will fail to load the Ajax content and fail silently at that. You can click the link until you are blue in the face but nothing happens. A dirty hack to avoid this is just allowing the browser to load the document if somebody really tries to load an external link.

Check out this allowing external links to be followed to see what it does.

$(document).ready(function(){
$('.ajaxtrigger').click(function(){
var url = $(this).attr('href');
if(url.match('^http')){
return true;
} else {
$('#target').load(url);
return false;
}
});
});

Proxying with PHP

If you look around the web you will find the solution in most of the cases to be PHP proxy scripts (or any other language). Something using cURL could be for example proxy.php:

<?php
$url = $_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $content;
?>

People then could use this with a slightly changed script (using a proxy):

$(document).ready(function(){
$('.ajaxtrigger').click(function(){
var url = $(this).attr('href');
if(url.match('^http')){
url = 'proxy.php?url=' + url;
}
$('#target').load(url);
return false;
});
});

It is also a spectacularly stupid idea to have a proxy script like that. The reason is that without filtering people can use this to load any document of your server and display it in the page (simply use firebug to rename the link to show anything on your server), they can use it to inject a mass-mailer script into your document or simply use this to redirect to any other web resource and make it look like your server was the one that sent it. It is spammer’s heaven.

Use a white-listing and filtering proxy!

So if you want to use a proxy, make sure to white-list the allowed URIs. Furthermore it is a good plan to get rid of everything but the body of the other HTML document. Another good idea is to filter out scripts. This prevents display glitches and scripts you don’t want executed on your site to get executed.

Something like this:

<?php
$url = $_GET['url'];
$allowedurls = array(
'http://developer.yahoo.com',
'http://icant.co.uk'
);
if(in_array($url,$allowedurls)){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$content = preg_replace('/.*<body[^>]*>/msi','',$output);
$content = preg_replace('/</body>.*/msi','',$content);
$content = preg_replace('/<?/body[^>]*>/msi','',$content);
$content = preg_replace('/[r|n]+/msi','',$content);
$content = preg_replace('/<--[Ss]*?-->/msi','',$content);
$content = preg_replace('/<noscript[^>]*>[Ss]*?</noscript>/msi',
'',$content);
$content = preg_replace('/<script[^>]*>[Ss]*?</script>/msi',
'',$content);
$content = preg_replace('/<script.*/>/msi','',$content);
echo $content;
} else {
echo 'Error: URL not allowed to load here.';
}
?>

Pure JavaScript solution using YQL

But what if you have no server access or you want to stay in JavaScript? Not to worry – it can be done. YQL allows you to load any HTML document and get it back in JSON. As jQuery has a nice interface to load JSON, this can be used together to achieve what we want to.

Getting HTML from YQL is as easy as using:

select * from html where url="http://icant.co.uk"

YQL does a few things extra for us:

  • It loads the HTML document and sanitizes it
  • It runs the HTML document through HTML Tidy to remove things .NETnasty frameworks considered markup.
  • It caches the HTML for a while
  • It only returns the body content of the HTML – so no styling (other than inline styles) will get through.

As output formats you can choose XML or JSON. If you define a callback parameter for JSON you get JSON-P with all the HTML as a JavaScript Object – not fun to re-assemble:

foo({
"query":{
<a href=""1" title="">count</a>",
<a href=""2010-01-10T07:51:43Z" title="">created</a>",
<a href=""en-US" title="">lang</a>",
<a href=""2010-01-10T07:51:43Z" title="">updated</a>",
<a href=""http://query.yahoo[...whatever...]k%22" title="">uri</a>",
"results":{
"body":{
"div":{
<a href=""doc2" title="">id</a>",
<a href="[{"id":"hd" title="">div</a>",
<a href=""icant.co.uk" title="">h1</a> - everything Christian Heilmann"
},
{<a href=""bd" title="">id</a>",
"div":[
{<a href="[{"h2":"About" title="">div</a> this and me","[... and so on...]
}}}}}}}});

When you define a callback with the XML output you get a function call with the HTML data as string in an Array – much easier:

foo({
"query":{
<a href=""1" title="">count</a>",
<a href=""2010-01-10T07:47:40Z" title="">created</a>",
<a href=""en-US" title="">lang</a>",
<a href=""2010-01-10T07:47:40Z" title="">updated</a>",
<a href=""http://query.y[...who" title="">uri</a> cares...]%22"},
"results":[
"<body>n    <div id="doc2">n      <div id="hd">n
<h1>icant.co.uk - everything Christian Heilmann</h1>n
... and so on ..."
]
});

Using jQuery’s getJSON() method and accessing the YQL endpoint this is easy to implement:

$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=xml'&callback=?",
function(data){
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
}
);

Putting it all together you have a cross-domain Ajax solution with jQuery and YQL:

$(document).ready(function(){
var container = $('#target');
$('.ajaxtrigger').click(function(){
doAjax($(this).attr('href'));
return false;
});
function doAjax(url){
// if it is an external URI
if(url.match('^http')){
// call YQL
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(url)+
"%22&format=xml'&callback=?",
// this function gets the data from the successful
// JSON-P call
function(data){
// if there is data, filter it and render it out
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
// otherwise tell the world that something went wrong
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
}
);
// if it is not an external URI, use Ajax load()
} else {
$('#target').load(url);
}
}
// filter out some nasties
function filterData(data){
data = data.replace(/<?/body[^>]*>/g,'');
data = data.replace(/[r|n]+/g,'');
data = data.replace(/<--[Ss]*?-->/g,'');
data = data.replace(/<noscript[^>]*>[Ss]*?</noscript>/g,'');
data = data.replace(/<script[^>]*>[Ss]*?</script>/g,'');
data = data.replace(/<script.*/>/,'');
return data;
}
});

This is rough and ready of course. A real Ajax solution should also consider timeout and not found scenarios. Check out the full version with loading indicators, error handling and yellow fade for inspiration.

you can find original post here : http://www.wait-till-i.com/2010/01/10/loading-external-content-with-ajax-using-jquery-and-yql/

Using jQuery to post an array to a ColdFusion Component

November 15th, 2010

A reader sent in an interesting question today. He was trying to make use of jQuery to post an array of data to a ColdFusion component. His CFC was expecting, and demanding, an array argument. Whenever he fired off the request though he received an error from ColdFusion saying the argument was not a valid array. Let’s look at an example of this so it is more clear.

I’ll start off with my server side component. It handles the incredibly complex task of returning the size of an array.

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org

<cfcomponent>

<cffunction name="handleArray" access="remote" returnType="numeric">
	<cfargument name="data" type="array" required="true">
	<cfreturn arrayLen(arguments.data)>
</cffunction>

</cfcomponent>

1  <cfcomponent>
2
3  <cffunction name=”handleArray” access=”remote” returnType=”numeric”>
4      <cfargument name=”data” type=”array” required=”true”>
5      <cfreturn arrayLen(arguments.data)>
6  </cffunction>
7
8  </cfcomponent>

On the client side, I’m going to use jQuery to post a static query to the CFC. This will happen immediately on document load so I don’t have to bother clicking a button or anything fancy like that. (Note, in the code block below I’ve removed the html, head, and body tags since they are all empty. I do have a script block to load in the jQuery library though.)

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org

$(document).ready(function() {
	var mydata = [1,2,3,4,5,"Camden,Raymond"];
	$.post("test.cfc", {method:"handleArray",data:mydata, returnFormat:"plain"}, function(res) {
		alert($.trim(res));
	})

})

1  $(document).ready(function() {
2      var mydata = [1,2,3,4,5,"Camden,Raymond"];
3      $.post(“test.cfc”, {method:”handleArray”,data:mydata, returnFormat:”plain”}, function(res) {
4          alert($.trim(res));
5      })
6
7  })

So, what would you expect to happen here? Well first off, it is important to remember that we are talking about an HTTP post here. You cannot send a complex data type of POST. It must be encoded somehow. jQuery does indeed encode the data – just not how you would expect it. Upon running this and examining the POST data in my Chrome dev tools, I see the following:

Not what you expected, right? You can see why ColdFusion complained. The “Data” argument doesn’t exist. Instead we have a lit of things named like Data, but not quite. You can try using toString on the array, but that doesn’t correctly handle the comma in the data. So what to do?

What I recommended was converting the array to JSON. It always surprises me when I remember that jQuery can’t produce JSON on its own, but there are plugins out there that will do it it for you. Because JSON is a string format though I thought I’d write up a quick function to generate the string for me. This function makes the assumption that are array only contains simple values of numbers and strings.

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org

$(document).ready(function() {
	var mydata = [1,2,3,4,5,"Camden,Raymond"];
	var myds = serialize(mydata)
	$.post("test.cfc", {method:"handleArray",data:mydata, returnFormat:"plain"}, function(res) {
		alert($.trim(res));
	})

	function serialize(arr) {
		var s = "[";
		for(var i=0; i<arr.length; i++) {
			if(typeof(arr[i]) == "string") s += '"' + arr[i] + '"'
			else s += arr[i]
			if(i+1 < arr.length) s += ","
		}
		s += "]"
		return s
	}
})

1  $(document).ready(function() {
2      var mydata = [1,2,3,4,5,"Camden,Raymond"];
3      var myds = serialize(mydata)
4      $.post(“test.cfc”, {method:”handleArray”,data:mydata, returnFormat:”plain”}, function(res) {
5          alert($.trim(res));
6      })
7
8      function serialize(arr) {
9          var s = “[";
10          for(var i=0; i<arr.length; i++) {
11              if(typeof(arr[i]) == “string”) s += ‘”‘ + arr[i] + ‘”‘
12              else s += arr[i]
13              if(i+1 < arr.length) s += “,”
14          }
15          s += “]”
16          return s
17      }
18  })

As you can see, I wrote a serialize function to handle converting the array into a JSON-encoded array. This isn’t the only change though. We still aren’t sending an array to the CFC. It’s a string. So I rewrote the CFC to handle it a bit better:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org

<cfcomponent>

<cffunction name="handleArray" access="remote" returnType="numeric">
	<cfargument name="data" type="any" required="true">
	<cfif isJSON(arguments.data)>
		<cfset arguments.data  = deserializeJSON(arguments.data)>
	</cfif>
	<cfreturn arrayLen(arguments.data)>
</cffunction>

</cfcomponent>

1  <cfcomponent>
2
3  <cffunction name=”handleArray” access=”remote” returnType=”numeric”>
4      <cfargument name=”data” type=”any” required=”true”>
5      <cfif isJSON(arguments.data)>
6          <cfset arguments.data = deserializeJSON(arguments.data)>
7      </cfif>
8      <cfreturn arrayLen(arguments.data)>
9  </cffunction>
10
11  </cfcomponent>

I normally don’t like to “muck” up my code so that it has outside knowledge like this. However, I’d probably have a remote service component in front of this component anyway and the whole issue would become moot.

There are probably many better ways of handling this. Any suggestions?

you can find original post here : http://www.coldfusionjedi.com/index.cfm/2010/3/23/Using-jQuery-to-post-an-array-to-a-ColdFusion-Component

How CSS and JavaScript Are Different

November 15th, 2010

So, what’s this important difference?

In CSS, style rules are automatically applied to any element that matches the selectors, no matter when those elements are added to the document (DOM).

In JavaScript, event handlers that are registered for elements in the document apply only to those elements that are part of the DOM at the time the event is attached. If we add similar elements to the DOM at a later time, whether through simple DOM manipulation or ajax, CSS will give those elements the same appearance, but JavaScript will not automatically make them act the same way.

For example, let’s say we have “<button>Alert!</button>” in our document, and we want to attach a click handler to it that generates an alert message. In jQuery, we might do so with the following code:

PLAIN TEXT

JavaScript:

  1. $(document).ready(function() {
  2. $(‘button.alert’).click(function() {
  3. alert(‘this is an alert message’);
  4. });
  5. });

Here we are registering the click handler for the button with a class of “alert” as soon as the DOM has loaded. So, the button is there, and we have a click function bound to it. If we add a second <button> later on, however, it will know nothing about that click handler. The click event had been dealt with before this second button existed. So, the second button will not generate an alert.

Let’s test what we’ve just discussed. I’ve added a script with the above three lines of jQuery code so that the following button will produce an alert message when clicked. Try it:

Events Don’t Work with Added Elements

Now, let’s create a new button (if we don’t already have a second one) using jQuery code like this:

PLAIN TEXT

JavaScript:

  1. $(‘#create-button’).click(function() {
  2. if ( $(‘button.alert’).length <2) {
  3. $(‘<button>Not another alert’).insertAfter(this);
  4. }
  5. return false;
  6. });

create the button

Have you clicked the link to create the second button? Great. Now click that button. It does nothing. Just as expected.

CSS Continues to “Work” with Newly Created Elements

Now let’s take a look at another example. In this one, we have three list items—two plain items and one with a class of special:

PLAIN TEXT

HTML:

  1. <ul id=”list1″ class=”eventlist”>
  2. <li>plain</li>
  3. <li class=”special”>special <button>I am special</button></li>
  4. <li>plain</li>
  5. </ul>

Press the “I am special” button to create a new list item with a class of “special”:

  • plain
  • special
  • plain

Notice that, like the first special li, the new one has the yellow background. The CSS has come through for us. But press the newly created “I am new” button and, just as with the second alert above, nothing happens. The jQuery code we’re using to add the new item says that upon clicking a button inside a list item with a class of “special” (which itself is inside an element with id of “list1″) a new list item with class=”special” should be inserted after the list item in which the button was clicked:

PLAIN TEXT

JavaScript:

  1. $(document).ready(function() {
  2. $(‘#list1 li.special button’).click(function() {
  3. var $newLi = $(‘<li>special and new <button>I am new</button></li>’);
  4. $(this).parent().after($newLi);
  5. });
  6. });

So, how can we get the events to carry over to the new elements? Two common approaches are event delegation and “re-binding” event handlers. In this entry, we’ll examine event delegation; in part 2, we’ll explore ways to re-bind.

Event Delegation: Getting Events to Embrace New Elements

The general idea of event delegation is to bind the event handler to a containing element and then have an action take place based on which specific element within that containing element is targeted. Let’s say we have another unordered list: <ul id="list2"> ... </ul>. Instead of attaching the .click() method to a button — $('#list2 li.special button').click(...) — we can attach it to the entire surrounding <ul>. Through the magic of “bubbling,” any click on the button is also a click on the button’s surrounding list item, the list as a whole, the containing div, and all the way up to the window object. Since the <ul> that gets clicked is the same one each time (we’re only creating items within the <ul>), the same thing will happen when clicking on all of the buttons, regardless of when they were created.

When we use event delegation, we need to pass in the “event” argument. So, in our case, instead of .click(), we’ll have .click(event). We don’t have to name this argument event. We can call it e or evt or gummy or whatever we want. I just like to use labels that are as obvious as possible because I have a hard time keeping track of things. Here is what we have so far:

PLAIN TEXT

JavaScript:

  1. $(document).ready(function() {
  2. $(‘#list2′).click(function(event) {
  3. var $newLi = $(‘<li>special and new <button>I am new</button></li>’);
  4. });
  5. });

So far, the code is very similar to our first attempt, except for the selector we’re starting with (#list2) and the addition of the event argument. Now we need to determine whether what is being clicked inside the <ul> is a “special” button or not. If it is, we can add a new <li>. We check the clicked element by using the “target” property of the event argument:

PLAIN TEXT

JavaScript:

  1. $(document).ready(function() {
  2. $(‘#list2′).click(function(event) {
  3. var $newLi = $(‘<li>special and new <button>I am new</button></li>’);
  4. var $tgt = $(event.target);
  5. if ($tgt.is(‘button’)) {
  6. $tgt.parent().after($newLi);
  7. }
  8. // next 2 lines show that you’ve clicked on the ul
  9. var bgc = $(this).css(‘backgroundColor’);
  10. $(this).css({backgroundColor: bgc == ‘#ffcccc’ || bgc == ‘rgb(255, 204, 204)’ ? ‘#ccccff’ : ‘#ffcccc’});
  11. });
  12. });

Line 4 above puts the target element in a jQuery wrapper and stores it in the $tgt variable. Line 5 checks whether the click’s target is a button. If it is, the new list item is inserted after the parent of the clicked button. Let’s try it:

  • plain
  • special
  • plain

I put an additional two lines at the end to demonstrate that a click on one of the buttons is still considered a click on the <ul> You’ll see that clicking anywhere within the <ul> toggles its background between pink and blue.

It’s probably worth noting that jQuery makes working with the event argument cross-browser friendly. If you do this sort of thing with plain JavaScript and DOM nodes, you’d have to do something like this:

var list2 = document.getElementById('list2');
list2.onclick = function(e) {
  var e = e || window.event;
  var tgt = e.target || e.srcElement;
  if (tgt.nodeName.toLowerCase() == 'button') {
    // do something
  }
};

As you can see, it’s a bit of a hassle.

Another Huge Benefit of Event Delegation

Event delegation is also a great way to avoid crippling the user’s browser when you’re working with a huge document. For example, if you have a table with thousands of cells, and you want something to happen when the user clicks on one, you won’t want to attach a click handler to every single one of them (believe me, it can get ugly). Instead, you can attach the click handler to a single table element and use event.target to pinpoint the cell that is being clicked:

PLAIN TEXT

JavaScript:

  1. $(document).ready(function() {
  2. $(‘table’).click(function(event) {
  3. var $thisCell, $tgt = $(event.target);
  4. if ($tgt.is(‘td’)) {
  5. $thisCell = $tgt;
  6. } else if ($tgt.parents(‘td’).length) {
  7. $thisCell = $tgt.parents(‘td:first’);
  8. }
  9. // now do something with $thisCell
  10. });
  11. });

Note that I had to account for the possibility of clicking in a child/descendant of a table cell, but this seems a small inconvenience for the great performance increase that event delegation affords.

you can find original post here : http://www.learningjquery.com/2008/03/working-with-events-part-1#

How To: AJAX Post Pagination in MooTools

November 15th, 2010

Ever wanted to browse through the older post archives only to be staring at the screen for ages in frustration while the content slowly loads up? A quick fix would be to make use of AJAX to load the post archives. In this tutorial, I will show you how to do that using the ever popular JavaScript framework; MooTools on a typical 2 column WordPress theme.

The code is quite easily digestible and with a little CSS tweaking, you could get it to work for your theme.

Step 1: Readying the Files

Download the file mootools_core.js and upload it into a folder within the directory of your active WordPress theme and name it as js.

I only included components needed for AJAX post pagination in this MooTools build. You are however welcome to create a new one with components you would like to use.

Create a blank JavaScript file called ajax.js and upload into the js folder. At this point of time, you should have these 2 files in your js folder.

yoursite.com/wp-content/themes/yourtheme/js/mootools_core.js
yoursite.com/wp-content/themes/yourtheme/js/ajax.js

Step 2: Edit header.php

You have to tell the browser that we have a JavaScript file to use. Add the following lines into your header.php just before the closing </head> tag.

<?php wp_enqueue_script('mootools', '/wp-content/themes/yourtheme/js/mootools_core.js')); ?>
<?php wp_enqueue_script('mootools_ajax', '/wp-content/themes/yourtheme/js/ajax.js')); ?>

Where yourtheme is the folder name of your active theme.

Step 3: Edit index.php

When it comes to AJAX pagination, we only want to refresh the post listings and not other portions of your site. The following code snippets will tell the browser to skip loading the entire page.

The top of your index.php file should have the following line:

1
<?php get_header(); ?>

Replace that line with this:

1
2
3
<?php if (!isset($_GET['ajax'])) { ?>
<?php get_header(); ?>
<?php } ?>

Similarly, at the very end of the file you should see:

1
2
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Now replace it with this:

1
2
3
4
<?php if (!isset($_GET['ajax'])) { ?>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
<?php } ?>

To avoid any possible causes for the code not to work, do ensure that your HTML structure is identical to the ones listed below. We will need to have a div with an id of ‘post’ nesting the loop.

Go back into index.php and add the div before the start of the loop, i.e. the end result should look like this:

1
2
<div id="post">
<?php if (have_posts()) { ?>

Be sure to also close the <div> after the loop ends.

1
2
<?php } ?>
</div>

We also need a div with a CSS class of ‘page-navi’ to nest the post pagination links.

1
2
3
4
<div class="page-navi">
	<?php next_posts_link('- Older Posts -') ?>
	<?php previous_posts_link('- Newer Posts -') ?>
</div>

Step 4: Writing your ajax.js

This is basically what goes on in your JavaScript file. I have left some pretty detailed comments so that you know what the code is all about.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//function used to handle AJAX post pagination
function ajaxLinks(id, container) {

	//looks for all instances of id
	$$(id).each(function(ele) {		

		//what happens when the particular instance is clicked on
		ele.addEvent('click', function(e) {
			e = new Event(e).stop();
			var alink = ele.getProperty('href');
			var url = alink;

			//construct the new URL with a parameter indicating how it should load the page (fully or a portion of it)
			if (alink.indexOf('?') != -1) {
				url += "&ajax=y";
			} else {
				url += "?ajax=y";
			}				

			//this is where the magic happens
			var ajaxLink = new Request.HTML({
				onRequest: function() {}, //what happens during an ajax request is made
				onSuccess: function() { //what happens when an ajax request is completed successfully
					new Fx.Scroll(document.body, {'duration': 'long'}).start(0, 0); //scrolls to the top of the page once your content is loaded
					ajaxLinks('.page-navi a', 'post'); //calls the function again so that it will add ajax post pagination to your newly loaded page
				}, 

				onFailure: function() {}, //what happens when an ajax request fails
				update: $(container) //#post which is your container gets updated
			}).get(url);
		});		    

	});

}

//needed for the MooTools build to be executed
window.addEvent('domready', function(dom){
	ajaxLinks('.page-navi a', 'post'); //Of course all of this will not be completed until you call the function to action
});

Step 5: Customization

As you would have probably guessed, this is a very basic implementation of how AJAX post pagination works in WordPress themes.

I would love to let your imagination run wild and see what you come up. Of course you need to have a little knowledge in CSS to get it done. Customizations can be made in the 3 different events (onRequest, onSuccess and onFailure).

If you have any doubts or feedback about this how-to. I would love to hear of it.

you can find original post here : http://www.problogdesign.com/wordpress/how-to-ajax-post-pagination-in-mootools/