Web Development: Progressive Enhancement – Part 1

I am starting a series of posts as an extension to Web Standards and Accessibility. These posts will be dedicated to explaining how to make a habit of progressive enhancement instead of falling back on graceful degradation. It will also give you the tools to pass this on to your coworkers and developers.

Step 1: Text is all you need, assume and start with nothing.

Download Lynx (Mac | PC). Load up your web page and see if you can navigate to your desired information. Does the order of the content look logical? Is anything important missing? Are you seeing text you should not be seeing?

Often this is the first step overlooked by web developers, not because its hard but because it takes extra time. Pressure from management to get projects done can push accessibility low on the priority list. You can learn a great deal by browsing your site from this browser, how easy or difficult it can be. Try it out for at least 20 minutes, see if you get frustrated or not.

Step 2: Building up, SEO included

buildings-seo

Semantic code has built in search engine optimization. Naming your html id’s and classes by what they contain instead of their visual position not only benefits developers but also search engines. When a computer knows what content you are describing it can bring it to the attention of someone searching for it. When you use javascript to load content dynamically on the page you can be hiding that content from search engines and in turn from your potential users.

If something is important enough for search engines to pick up it should be in the html file and not loaded afterward. As you can see from the screen shot in step 1 the login form is currently in the HTML although it is only visible by clicking on a link that is activate via javascript. The login form is not something a search engine would care about so it should really be removed from the HTML and loaded into the DOM once the page has loaded with javascript.

Step 3: Technology applied in layers, CSS next

picture-4

After your site works in a text only browser in a linear fashion without javascript or images start applying some style. Applying the style with CSS will hopefully give you a central location to update the look of your site. One important thing to think of when writing CSS is to be diligent and keep your nesting in a logical order so you or another developer can edit it in the future without wasting time searching through all the inheritance rules.

There are thousands of techniques to writing CSS, I am not going to dictate which one is better than the other, but what I want to convey is thinking about every rule you add and ask yourself if it is necessary. Each added rule adds weight to your page, rendering time and complexity for future development changes. Use HTML tags appropriately, header tags for headers, p tags for paragraphs and so on so search engines know what is on your page and so you don’t have tons of container DIV’s weighing down your page.

Step 4: Images (png’s mainly)

picture-6

As the design of web pages get more intricate it becomes more beneficial to use alpha transparent images to minimize the number and filesize of images. Older browsers (Netscape and IE6 mainly) do not support these alpha transparent images natively. Although there are techniques to add this functionality, in most cases the extra rendering time and weight is not worth it.

One rule as a web developer/designer that you have to keep in mind is supporting multiple browsers doesn’t mean you have to guarantee the same experience across the board. There is nothing wrong with serving up different images depending on capabilities as long as the users experience is not impaired by the lack of images.

The example above is IE6 on the left and Firefox on the right. As you can see the left image is jagged because it is just a transparent GIF and the smooth image on the right is a PNG with alpha transparency. The switch was done with an <!–[if lt IE 7]> conditional. Same web page but different experience depending on the users browser, adding functionality if it is available.

The Goal

To reach everyone possible. Think of a web page like a building, it has to be accessible by all no matter how it looks. Starting out with the absolute basics and building up keeping accessibility in mind benefits everyone. Your users, designers and developers will thank you. Although these things seem really basic, they are the building blocks to a successful web site.

Next time: Javascript DOM Manipulation, AJAX and Flash

Source from .eduGuru

Posted in Web development | Tagged , , | Leave a comment

Pagination for product options in admin

How to add pagination to product options in Admin ?

This customisation is for all UK2.net e-commerce package customers and Tradingeye users (5.04+)

product-options-uk2-tradingeye

Files need to modify:

modules/ecom/templates/admin/optionHome.tpl.htm
modules/ecom/classes/admin/option_interface.php

Edit the option_interface.php class as following steps:

1.    Modify the c_optionInterface() function

Before edit:

#CONSTRUCTOR
function c_optionInterface()
{
$this->err=0;
$this->errMsg="";
$this->libFunc=new c_libFunctions();
}

After edit:

#CONSTRUCTOR
function c_optionInterface()
{
$this->err=0;
$this->errMsg="";
$this->libFunc=new c_libFunctions();
 
#INITIALISING PAGINATION VARIABLES
$this->pageTplPath=MODULES_PATH."default/templates/admin/";
$this->pageTplFile="pager.tpl.htm";
$this->pageSize="50"; #NUMBER OF ITEMS DISPLAYING PER PAGE
}

2.    Modify the m_showOptions() function

Replace everything between these 2 parts

Part1(line 47):

$resOption=$this->obDb->fetchQuery();
$varCount=$this->obDb->record_count;

Part2(line 70):

$query= "SELECT *  FROM ".CHOICES." order by vName" ;

By this code:

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
#ADDED PAGINATION FOR PRODUCTS
$extraString    ="action=ec_option.home";
$pn                =new PrevNext($this->pageTplPath, $this->pageTplFile,$this->obDb);
$pn->formno    =1;
$navArr            =$pn->create($query, $this->pageSize, $extraString);
 
$resOption        =$navArr['qryRes'];
$recordCount    =$navArr['selRecs'];
$totalRecord    =$navArr['totalRecs'];
$row1             =$navArr;
 
#BLANK OUT THE PAGINATION
$this->ObTpl->set_var("TPL_VAR_PAGINATION", "");
 
if($totalRecord>$this->pageSize){
$this->ObTpl->set_var("TPL_VAR_PAGINATION", $row1['pnContents']);
}
 
$this->ObTpl->set_var("TPL_TOTAL_RECORDS",$varCount);
if($totalRecord>0)
{
for($i=0;$i< $recordCount;$i++)
{
if($resOption[$i]->iState==1)
{
$this->ObTpl->set_var("TPL_VAR_CHECKED","checked");
}
else
{
$this->ObTpl->set_var("TPL_VAR_CHECKED","");
}
$this->ObTpl->set_var("TPL_OPTION_ID",$resOption[$i]->iOptionid_PK);
$this->ObTpl->set_var("TPL_VAR_TITLE",$resOption[$i]->vName);
$this->ObTpl->set_var("TPL_VAR_DESC",$resOption[$i]->vDescription);
$this->ObTpl->set_var("TPL_VAR_MESSAGE","");
$this->ObTpl->parse("dspstdoption_blk","TPL_STDOPTIONS_BLK",true);
}
}

Edit the optionHome.tpl.htm template file as below:

1.    Add line 16, add this code for the pagination

{TPL_VAR_PAGINATION}

Finally, make sure you replace 2 other files from the download ZIP

1.    modules/default/prevNext.php
2.    modules/default/templates/main/pager.tpl.htm

That’s it. Please note this modification is for Standard Options only. You can follow the same method to apply the pagination for Custom Option or even product listing under department.

Feel free to ask me any question.

Download pagination for product options Version 1.00
Posted in PHP, Tradingeye & UK2 Ecommerce, Web development | Tagged , , , | Leave a comment

Prestashop Theme (sieuthilondon)

I’m trying to create a simple theme for Prestashop e-commerce system (open source). The theme is not 100% completed but ideally It would be good for you to have a starting point of creating 2 columns layout and beautiful header and footer to work with.

Free prestashop theme (sieuthilondon)

Free prestashop theme (sieuthilondon)

Welcome your feedback.  Cheers!

Download Free prestashop theme sieuthilondon Version 1.00

Posted in Web development | Tagged , , , , | 10 Comments

Transparent PNGs in Internet Explorer 6 (IE6) with SuperSleight

If you have problem with using PNGs images on IE6 then here probably is easiest way to fix the problem

ie6 png transparency

Transparency issue with PNG in IE6

Step 1: Download the SuperSleight.zip file from bottom of the entry
Step 2: Extract the file and place these 2 files: supersleight-min.js and x.gif under your javascript folder
Step 3: Put this code below in between the <head> </head> tags
[code]
<!--[if lte IE 6]>
<script type="text/javascript" src="supersleight-min.js"></script>

<![endif]-->
[/code]

Step 4: You’re done! Click here if you want to know more how it works or even this one.

http://24ways.org/2007/supersleight-transparent-png-in-ie6
http://www.twinhelix.com/css/iepngfix/demo/

Download Super Sleight

Posted in PHP, Web development | Tagged , , | 1 Comment

Google e-commerce tracking modification for Tradingeye and UK2.net ecommerce package

his modification is for Tradingeye accessible e-commerce system and the latest UK2.net E-commerce package to help you track visitor movement through checkout pages. To get better understanding and the benefit of this feature, please refer to these 2 article as below:

google ecommerce tracking code for Tradingeye and Uk2 ecommerce

1. Google Ecommerce Tracking Code

2. Analytics Talk

Now, please follow these steps

Step 1: Enabling E-Commerce Reporting in the Profile

The first step of tracking e-commerce transactions is to enable e-commerce reporting for your website’s profile. To enable e-commerce reporting, please follow these steps:

Log in to your account.
Click Edit next to the profile you’d like to enable.
On the Profile Settings page, click edit next to Main Website Profile Information.
Change the E-Commerce Website radio button from No to Yes.

Step 2: Receipt Page Format

Tradingeye and UK2.net payment process is slightly different from others. Once customer completed their transaction, he will be taken to an acknowlegdement (thank-you)  page rather than a receipt page. He then has to click on the link “view your receipt” to see his receipt. Thus, we need to modifify these following files:

/modules/ecom/templates/main/orderProcessed.tpl.htm
/modules/ecom/classes/main/receipt.php

Lets get the ball rolling!

2.1: Place this code below at the bottom of the file orderProcessed.tpl.htm

<pre lang=”html”><!– BEGIN TPL_GOOGLE_ECOMMERCE_TRACKING_BLOCK –>
<script type=”text/javascript”><!–

var gaJsHost = ((“https:” == document.location.protocol ) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));

// –></script>

<script type=”text/javascript”><!–
var pageTracker = _gat._getTracker(“UA-4440573-2″);
pageTracker._initData();
pageTracker._addTrans(
“{TPL_VAR_ORDER_ID}”, // order ID – required
“{TP_VAR_STORE_NAME}”, // affiliation or store name
“{TPL_VAR_TOTAL}”, // total – required
“{TPL_VAR_TAX_TOTAL}”, // tax
“{TPL_VAR_SHIPPING_COST}”, // shipping
“{TPL_VAR_CITY}”, // city
“{TPL_VAR_COUNTY}”, // state or province
“{TPL_VAR_COUNTRY}” // country
);

// add items might be called for every item in the shopping cart
<! BEGIN TPL_GOOGLE_ADDITEM_BLK –>
pageTracker._addItem(
“{TPL_VAR_ORDER_ID}”, // order ID – required
“{TPL_VAR_SKU_CODE}”, // SKU/code
“{TPL_VAR_PRODUCT_TITLE}”, // product name
“{TPL_VAR_CATEGORY}”, // category or variation
“{TPL_VAR_PRODUCT_PRICE}”, // unit price – required
“{TPL_VAR_QUANTITY}” // quantity – required
);
<!– END TPL_GOOGLE_ADDITEM_BLK –>
pageTracker._trackTrans(); //submits order info in hidden form after page load
// –></script>
<!– END TPL_GOOGLE_ECOMMERCE_TRACKING_BLOCK –></pre>

You need to replace this “UA-xxxxxx-xx” to your own Google Tracking ID

2.2:  Modify the receipt.php class.

Under the method (function) m_orderProcessed()

At Line 47, Look for:


<pre lang=”php”>

#DECLARE BLOCKS $this->ObTpl->set_block(“TPL_ORDER_FILE”,”TPL_ORDERSTATUS_BLK”,”orderstatus_blk”);

$this->ObTpl->set_block(“TPL_ORDER_FILE”,”TPL_BACKORDER_BLK”,”backorder_blk”);

<pre>

And add:

<pre lang=”php”>

$this->ObTpl->set_block(“TPL_ORDER_FILE”,”TPL_GOOGLE_ECOMMERCE_TRACKING_BLOCK”,”google_blk”);

$this->ObTpl->set_block(“TPL_GOOGLE_ECOMMERCE_TRACKING_BLOCK”,”TPL_GOOGLE_ADDITEM_BLK”,”item_blk”);

$this->ObTpl->set_var(“google_blk”,”");
$this->ObTpl->set_var(“item_blk”,”");

</pre>


Look for this comment

#FLAG TO INDICATE SEPERATE BACKORDER AND NORMAL ORDER

and replace all the code from there to

<pre lang=”php”>$this->ObTpl->set_var(“TPL_VAR_BACKORDERURL”,$backOrderUrl);</pre>

by the code below:

<pre lang=”php”>#FLAG TO INDICATE SEPERATE BACKORDER AND NORMAL ORDER
$_SESSION['backOrderSeperate']=$this->libFunc->ifSet($_SESSION,’backOrderSeperate’,’0′);
$this->obDb->query = “SELECT count(*) as cnt  FROM “.TEMPCART.” WHERE  vSessionId=’”.$this->sessionId.”‘”;
$rowCount=$this->obDb->fetchQuery();

if($_SESSION['backOrderSeperate']==1 && $rowCount[0]->cnt>0)
{
$this->ObTpl->parse(“backorder_blk”,”TPL_BACKORDER_BLK”);
}
else
{

#GETTING INVOICE DETAIL AND ADD TO GOOGLE ECOMMERCE API
$this->obDb->query = “SELECT tmOrderDate,vPayMethod,vShipDescription,fShipTotal,”;
$this->obDb->query.= “vFirstName,vLastName,vEmail,vAddress1,vAddress2,vCity,iInvoice,”;
$this->obDb->query.= “vState,vStateName,vCountry,vZip,vCompany,vPhone,vHomepage,”;
$this->obDb->query.= “vAltPhone,fCodCharge,fPromoValue,”;
$this->obDb->query.= “vDiscountCode,fDiscount,iGiftcert_FK,fGiftcertTotal,fMemberPoints,”;
$this->obDb->query.= “fTaxRate,fTaxPrice,tComments,vStatus,iPayStatus,fTotalPrice,iEarnedPoints,iCustomerid_FK”;
$this->obDb->query .= ” FROM “.ORDERS.” WHERE iOrderid_PK=’”.$this->request['mode'].”‘”;

$qryResult = $this->obDb->fetchQuery();
$rCount=$this->obDb->record_count;
if($rCount!=1)
{
$errrorUrl=SITE_URL.”index.php?action=error&mode=order”;
$this->libFunc->m_mosRedirect($this->libFunc->m_safeUrl($errrorUrl));
}

#PARSING VALUE TO TEMPLATE VARIABLE
$this->ObTpl->set_var(“TPL_VAR_ORDER_ID”,$this->libFunc->m_displayContent($qryResult[0]->iInvoice));
$this->ObTpl->set_var(“TP_VAR_STORE_NAME”,SITE_NAME);
$this->ObTpl->set_var(“TPL_VAR_TOTAL”,$qryResult[0]->fTotalPrice);
$this->ObTpl->set_var(“TPL_VAR_TAX_TOTAL”,0);
$this->ObTpl->set_var(“TPL_VAR_SHIPPING_COST”,$qryResult[0]->fShipTotal);
$this->ObTpl->set_var(“TPL_VAR_CITY”,$this->libFunc->m_displayContent($qryResult[0]->vCity));
$this->ObTpl->set_var(“TPL_VAR_COUNTY”,$this->libFunc->m_displayContent($qryResult[0]->vZip));
$this->ObTpl->set_var(“TPL_VAR_COUNTRY”,$this->libFunc->m_displayContent($qryResult[0]->vFirstName));

#GETTING PRODUCTS DETAIL AND ADD TO GOOGLE API
$this->obDb->query = “SELECT iOrderProductid_PK,iProductid_FK,iQty,OP.fPrice,”;
$this->obDb->query.= “fDiscount,OP.vTitle,OP.vSku,OP.iKit,OP.tShortDescription,OP.vSeoTitle, “;
$this->obDb->query.=”OP.iTaxable,OP.iFreeship,vPostageNotes,vDownloadablefile “;
$this->obDb->query .= ” FROM “.ORDERPRODUCTS.” OP INNER JOIN “.PRODUCTS.” P ON OP.iProductid_FK=P.iProdId_PK WHERE iOrderid_FK=’”.$this->request['mode'].”‘”;
$rsOrderProduct=$this->obDb->fetchQuery();
$rsOrderProductCount=$this->obDb->record_count;
if ($rsOrderProductCount >0){
for($i=0;$i< $rsOrderProductCount;$i++){

#PARSING VALUE TO TEMPLATE VARIABLE
$this->ObTpl->set_var(“TPL_VAR_PRODUCT_TITLE”,$this->libFunc->m_displayContent($rsOrderProduct[$i]->vTitle));
$this->ObTpl->set_var(“TPL_VAR_SKU_CODE”,$this->libFunc->m_displayContent($rsOrderProduct[$i]->vSku));
$this->ObTpl->set_var(“TPL_VAR_PRODUCT_PRICE”,number_format($rsOrderProduct[$i]->fPrice,2,’.',”));
$this->ObTpl->set_var(“TPL_VAR_QUANTITY”,$rsOrderProduct[$i]->iQty);
$this->ObTpl->set_var(“TPL_VAR_ORDER_ID”,$this->libFunc->m_displayContent($qryResult[0]->iInvoice));
$this->ObTpl->set_var(“TPL_VAR_CATEGORY”,”"); # INITILISE CATEGORY NAME

#GETTING CATEGORY NAME BASED ON PRODUCT ID
/*
PLEASE NOTE: A PRODUCT COULD BE ASSOCIATED TO MANY DEPARTMENTS OR HOMEPAGE THEREFORE WE WILL GET
THE CATEGORY WHICH THAT PRODUCT WAS INITIALLY CREATED FROM.
*/

$this->obDb->query  = ” SELECT fusionId, iOwner_FK, iOwner_FK, vtype, iState, vOwnerType “;
$this->obDb->query .= ” FROM ” .FUSIONS . ” WHERE iSubId_FK = ‘”.$rsOrderProduct[$i]->iProductid_FK .”‘”;
$this->obDb->query .= ” AND vOwnerType =’department’ AND iState =’1′ AND iOwner_FK >0 ORDER BY fusionId”;

$rsFusion=$this->obDb->fetchQuery();

if ($this->obDb->record_count > 0){
#ASSIGN THE FIRST RECORD TO CATEGORY ID
$deptId = $rsFusion[0]->iOwner_FK;

$this->obDb->query  = ” SELECT iDeptid_PK, vTitle FROM “. DEPARTMENTS . ” WHERE iDeptid_PK = ‘”. $deptId .”‘”;
$rsDept    =$this->obDb->fetchQuery();

$this->ObTpl->set_var(“TPL_VAR_CATEGORY”,$this->libFunc->m_displayContent($rsDept[0]->vTitle));
}#if

#PARSE PRODUCTS DETAIL TO GOOGLE E-COMMERCE API
$this->ObTpl->parse(“item_blk”,”TPL_GOOGLE_ADDITEM_BLK”,true);
}#for loop
}#if $rsOrderProductCount

$this->ObTpl->parse(“google_blk”,”TPL_GOOGLE_ECOMMERCE_TRACKING_BLOCK”);
$this->ObTpl->parse(“orderstatus_blk”,”TPL_ORDERSTATUS_BLK”);
}
$backOrderUrl=$this->libFunc->m_safeUrl(SITE_URL.”ecom/index.php?action=checkout.backorder”);
$this->ObTpl->set_var(“TPL_VAR_BACKORDERURL”,$backOrderUrl);

</pre>

Notice

1. If your shop is using Off-site payment gateway such as Paypal or GoogleCheckout, it is required your customer going back to the merchant site otherwise no record is tracked.

2. The modified m_orderProcessed() method is also availablet to download from the link at bottom of the post.

Enjoy!

Download google ecommerce tracking code for tradingeye and uk2 Version 1

Posted in E-commerce, Games, PHP, Tradingeye & UK2 Ecommerce, Viva, Web development | Tagged , , , , , , | 17 Comments