Jump to content

[Tips] Amélioration générale de PS pour future release...


Recommended Posts

Bonjour,

 

Préambule : tout ce que je propose est systématiquement testé à la fois en local et sur un site en live. L'objectif est d'obtenir valid-xhtml10

 

 

J'ai noté quelques petites améliorations simples pour la prochaine release. Ces améliorations visent tantôt l'ergonomie (notées *), tantôt la validité du source xhtml (notées **)

 

1.° Fichier /root/admin/modules/blocknewsletter/blocknewsletter.tpl (**) :

 

code initial (j'ai dû faire des retours à la ligne pour la visibilité du code) :

 

[pre]<form action="?" method="post">

<input type="text" name="email" size="10"

value="{if $value}{$value}{else}{l s='your email' mod='blocknewsletter'}{/if}"

style="margin:0px 5px 5px 0px ; float:left;"

onclick="javascript:if(this.value=='{l s='your email' mod='blocknewsletter'}')this.value='';"/>

<br /><input type="image" src="{$img_dir}btn-ok.gif" name="submitNewsletter" />

<select name="action">

<option value="0"{if $action == 0} selected="selected"{/if}>{l s='Suscribe' mod='blocknewsletter'}</option>

<option value="1"{if $action == 1} selected="selected"{/if}>{l s='Unsuscribe' mod='blocknewsletter'}</option>

</select>

</form>

</div>

<div class="block_content_end"></div>[/pre]

 

A modifier par :

 

[pre]<form action="?" method="post">

<p><input type="text" name="email" size="10"

value="{if $value}{$value}{else}{l s='your email' mod='blocknewsletter'}{/if}"

style="margin:0px 5px 5px 0px ; float:left;"

onclick="javascript:if(this.value=='{l s='your email' mod='blocknewsletter'}')this.value='';" /></p>

<p><input type="image" src="{$img_dir}btn-ok.gif" name="submitNewsletter" /></p>

<p><select name="action">

<option value="0"{if $action == 0} selected="selected"{/if}>{l s='Suscribe' mod='blocknewsletter'}</option>

<option value="1"{if $action == 1} selected="selected"{/if}>{l s='Unsuscribe' mod='blocknewsletter'}</option>

</select></p>

</form>

</div>

<div class="block_content_end"></div>[/pre]

Commentaires : les inputs sont encapsulés dans des balises de paragraphes <p></p> beaucoup plus structurelles (et évite l'usage du <br /> qui n'a aucune place ici). L'espace après this.value=";" et avant la fermeture de l'input /> permet d'obtenir une validation w3c du source

 

2.° Fichier /root/themes/default/shopping_cart.tpl (*) :

 

ligne 115 : supprimez les balises <u></u> encapsulant l'affichage de "Transporteur" (le soulignement relève des CSS), ajoutez un attribut id="carrier" puis ajoutez dans /root/themes/default/css/styles.css :

 

ligne 1073 (propriété de la classe .cart_availability) : cursor:help;

 

après le style de div.order_carrier{ (...) }, ajoutez : b#carrier{border-bottom:1px solid #000} pour rétablir le soulignement.

 

Commentaires : amélioration générale du source (suppréssion de balises inutiles; changement du curseur en "?" au survol de l'image de disponibilité (le tooltip précise la signification du symbole, le curseur en point d'interrogation conforte sa raison d'être).

 

Je compte poursuivre mes investigations afin d'aider (dans les domaines qui sont à ma portée) les développeurs dans leur tâches essentielles : le code PHP. Si toutefois vous êtes demandeurs.

 

D'autre part, j'ai l'intention, pour mon usage personnel de PrestaShop, de transformer le source html afin d'obtenir une validation w3c totale en doctype xhtml Strict 1.0. Lourde tâche : j'envisage de substituer toutes les <table> (je n'aime pas beaucoup les tables :)  ) par des <dl>.

 

A bientôt,

 

Cordialement,

Link to comment
Share on other sites

3.° Fichier /root/admin/modules/blockcart/blockcart.tpl :

 

code initial :

 

[pre]<table class="cart">

{if $products}

{foreach from=$products item=value}

<tr>

<td class="cart_item">

<a href="{$base_dir}cart.php?delete&id_product={$value.id_product}&ipa={$value.id_product_attribute}">

<img src="{$module_dir}img/icon/delete.gif" alt="{l s='Delete' mod='blockcart'}" title="{l s='Delete' mod='blockcart'}" />

</a>

{$value.quantity} x

<a href="{$link->getProductLink($value.id_product, $value.link_rewrite)}">

{$value.name}{if isset($value.attributes_small)} {$value.attributes_small}{/if}

</a>

</td>

<td class="cart_price">{displayWtPrice p=$value.price_wt}</td>

</tr>

{/foreach}

{else}

<td>{l s='No products' mod='blockcart'}</td>

{/if}

{foreach from=$discounts item=discount}

<tr>

<td class="cart_item">

<a href="{$base_dir}order.php?deleteDiscount={$discount.id_discount}">

<img src="{$module_dir}img/icon/delete.gif" alt="{l s='Delete' mod='blockcart'}" title="{l s='Delete' mod='blockcart'}" />

</a>

{$discount.name}

</td>

<td class="cart_price">- {displayWtPrice p=$discount.value_real}</td>

</tr>

{/foreach}

</table>[/pre]

 

Nous n'avons pas vraiement d'utilité à invoquer une <table>, une liste non-ordonnée fera bien notre affaire. C'est totalement sémantique puisque cela correspond à une liste de "choses" sans ordre précis :) changez par :

 

[pre]<ul class="cart">

{if $products}

{foreach from=$products item=value}

<li class="cart_item">

<a href="{$base_dir}cart.php?delete&id_product={$value.id_product}&ipa={$value.id_product_attribute}">

<img src="{$module_dir}img/icon/delete.gif" alt="{l s='Delete' mod='blockcart'}" title="{l s='Delete' mod='blockcart'}" />

</a>

{$value.quantity} x

<a href="{$link->getProductLink($value.id_product, $value.link_rewrite)}">

{$value.name}{if isset($value.attributes_small)} {$value.attributes_small}{/if}

</a>

</li>

<li class="cart_price">{displayWtPrice p=$value.price_wt}</li>

{/foreach}

{else}

<li>{l s='No products' mod='blockcart'}</li>

{/if}

{foreach from=$discounts item=discount}

<li class="cart_item">

<a href="{$base_dir}order.php?deleteDiscount={$discount.id_discount}">

<img src="{$module_dir}img/icon/delete.gif" alt="{l s='Delete' mod='blockcart'}" title="{l s='Delete' mod='blockcart'}" />

</a>

{$discount.name}

</li>

<li class="cart_price">- {displayWtPrice p=$discount.value_real}</li>

{/foreach}

</ul>[/pre]

 

enfin, modifiez le style css comme suit (je commente les lignes pour indiquer l'apport des modifications ) :

 

[pre]/* table.cart a {

text-decoration: none;

color: #000000;

background-color: #EFEFEF;

}

 

td.cart_item {

width: 120px;

}

 

td.cart_item img {

float: right;

}

 

td.cart_price {

width: 54px;

text-align: right;

} */

 

ul.cart {

margin:0 6px;

padding:0;

font-size:11px;

font-weight:normal;

list-style:none;

}

 

ul.cart li a {

text-decoration: dotted;

color:#000;

background-color:#efefef;

}

 

li.cart_item {

width:100%;

padding:0;

clear:both;

}

 

li.cart_item img {

float:left;

padding-right:3px;

}

 

li.cart_price {

width:54px;

text-align:right;

float:right;

}[/pre]

 

Voilà. On obtient un panier du plus bel effet :)

 

Cordialement,

Link to comment
Share on other sites

4.° Les target="_blank" sur les liens afin de les ouvrir dans une nouvelle fenêtre ne sont pas valides au regard du w3C. Il est possible de remédier à ce phénomène par l'usage d'un petit javascript.

 

Ajoutez ce fichier en lui donnant le nom de "external.js" (à placer dans /root/js ) :

 

[pre]function externalLinks() {

if (!document.getElementsByTagName) return;

var anchors = document.getElementsByTagName("a");

for (var i=0; i<anchors.length; i++) {

  var anchor = anchors;

  if (anchor.getAttribute("href") &&

      anchor.getAttribute("rel") == "external")

    anchor.target = "_blank";

}

}

window.onload = externalLinks;[/pre]

 

On y fait référence dans le fichier /root/modeles/default/header.tpl en ajoutant cette ligne juste avant la balise </head> :

 

[pre] <script type="text/javascript" src="{$base_dir}js/external.js"></script>[/pre]

 

Dès lors, il suffira d'ajouter à tous vos liens nécessitant l'accès à un site, l'attribut : rel="external"

 

Ex. [pre]<a href="http://www.prestashop.com" title="Solution e-commerce d'enfer" rel="external">PrestaShop™</a>[/pre]

 

C'est absoluement valide, beaucoup plus sémantique...et légèrement web2 [cf. Microformats]

 

Voilà.

 

Cordialement,

Link to comment
Share on other sites

@jolvil :

 

Je ne pense pas que l'on arrive à une situation d'usine à gaz. Le javascript que je recommande et très simple et ne complique pas plus que cela les choses. Libre à vous d'utiliser... ou pas. L'attribut target="_blank" n'est pas supporté en xhtml. L'attribut proposé a cet avantage : il n'est pas intrusif (si javascript n'est pas actif, les liens s'ouvrent dans la même fenêtre - ce qui d'ailleurs ne pose pas de problème et c'est la recommandation officielle).

 

Poursuivons notre exploration de PrestaShop. Je me suis heurté au problème de validité des urls dans le code interne. Je viens de trouver la réponse (merci TextMate ;) ) PrestaShop est tellement bien conçu qu'une Classe Link.php se charge des liens!

 

 

5.° Validité w3C des esperluettes dans les urls des liens internes. Pour obtenir une telle validation du source xhtml, les esperluettes doivent être encodées & et non pas &.

 

Fichier /root/classes/Link.php

 

(je joint directement les fichier modifié)

 

[pre]<?php

 

 

 

/**

 

  * Link class, Link.php

 

  * Links management

 

  * @category classes

 

  *

 

  * @author PrestaShop <[email protected]>

 

  * @copyright PrestaShop

 

  * @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0

 

  * @version 0.8

 

  *

 

  */

 

 

 

class Link

 

{

 

/** @var boolean Rewriting activation */

 

private $allow;

 

private $url;

 

 

 

/**

 

  * Constructor (initialization only)

 

  */

 

function __construct()

 

{

 

$this->allow = intval(Configuration::get('PS_REWRITING_SETTINGS'));

 

$this->url = htmlentities($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8');

 

}

 

 

 

/**

 

  * Return the correct link for the product

 

  *

 

  * @param mixed $id_product Can be either the product object or the ID only

 

  * @param string $alias Friendly URL (only if $id_product is the object)

 

  * @return string link

 

  */

 

public function getProductLink($id_product, $alias = null, $ean13 = null)

 

{

 

if (!isset($this->allow)) $this->allow = 0;

 

if (is_object($id_product))

 

return ($this->allow == 1)?(__PS_BASE_URI__.intval($id_product->id).'-'.$id_product->link_rewrite.($id_product->ean13 ? '-'.$id_product->ean13 : '').'.html') :

 

(__PS_BASE_URI__.'product.php?id_product='.intval($id_product->id));

 

elseif ($alias)

 

return ($this->allow == 1)?(__PS_BASE_URI__.intval($id_product).'-'.$alias.($ean13 ? '-'.$ean13 : '').'.html') :

 

(__PS_BASE_URI__.'product.php?id_product='.intval($id_product));

 

else

 

return __PS_BASE_URI__.'product.php?id_product='.intval($id_product);

 

}

 

 

 

/**

 

  * Return the correct link for the category

 

  *

 

  * @param mixed $id_category Can be either the category object or the ID only

 

  * @param string $alias Friendly URL (only if $id_category is the object)

 

  * @return string link

 

  */

 

public function getCategoryLink($id_category, $alias = NULL)

 

{

 

if (is_object($id_category))

 

return ($this->allow == 1) ? (__PS_BASE_URI__.intval($id_category->id).'-'.$id_category->link_rewrite) :

 

(__PS_BASE_URI__.'category.php?id_category='.intval($id_category->id));

 

elseif ($alias)

 

return ($this->allow == 1) ? (__PS_BASE_URI__.intval($id_category).'-'.$alias) :

 

(__PS_BASE_URI__.'category.php?id_category='.intval($id_category));

 

else

 

return __PS_BASE_URI__.'category.php?id_category='.intval($id_category);

 

}

 

 

 

/**

 

  * Create link after language change

 

  *

 

  * @param integer $id_lang Language ID

 

  * @return string link

 

  */

 

public function getLanguageLink($id_lang)

 

{

 

return $this->getUrlWith('id_lang', intval($id_lang));

 

}

 

 

 

public function goLink($orderBy, $orderWay)

 

    {

 

if ((!empty($orderBy) AND !Validate::isOrderBy($orderBy)) OR

 

(!empty($orderWay) AND !Validate::isOrderWay($orderWay)))

 

return false;

 

 

 

        $n = 0;

 

$url = $this->url;

 

        foreach ($_GET as $k => $value)

 

if ($k != 'orderby' AND $k != 'orderway' AND Tools::getValue($k))

 

$url .= ((!$n++) ? '?' : '&').urlencode($k).'='.urlencode($value);

 

        return ($url.($n ? '&' : '?').'orderby='.urlencode($orderBy).'&orderway='.urlencode($orderWay));

 

    }

 

 

 

public function getUrlWith($key, $val)

 

    {

 

        $n = 0;

 

$url = $this->url;

 

        foreach ($_GET as $k => $value)

 

if ($k != $key AND Tools::getValue($k))

 

$url .= ((!$n++) ? '?' : '&').urlencode($k).'='.urlencode($value);

 

        return $url.($n ? '&' : '?').urlencode($key).'='.urlencode($val);

 

    }

 

 

 

public function goPage($p)

 

{

 

return $this->getUrlWith('p', intval($p));

 

}

 

}

 

 

 

?>[/pre]

 

Note : vous pouvez directement faire un copier/coller. Cette remarque et amélioration est importante, merci de l'intégrer dans la prochaine release.

 

Cordialement,

 

 

Link to comment
Share on other sites

Page de création d'un compte client.

 

6.° Validité du modèle /root/themes/authentication.tlp avec encapsulation des labels et inputs par des balises <p> :

 

[pre]<h1>{if !isset($email_create)}{l s='Log in'}{else}{l s='Create your account'}{/if}</h1>

<br />

{include file=$tpl_dir./errors.tpl}

{if isset($confirmation)}

<br />

<span class="confirmation">{l s='Your account has been successfully created'}.<br /><br />

<br /><br />

<a href="my-account.php"><img src="{$img_dir}arrow.gif" alt="{l s='Your account'}" title="{l s='Your account'}" class="img_middle" /> {l s='Access your account'}</a>

{else}

{if !isset($email_create)}

<div class="create_account">

<form action="{$request_uri}" method="post">

<h2 class="auth">{l s='Create your account'}</h2>

<div class="form_field_header">{l s='Enter your e-mail address to create your account'}.</div>

<div>{l s='E-mail address'}</div>

<p><input type="text" name="email_create" value="{if isset($smarty.post.email_create)}{$smarty.post.email_create|escape:'htmlall'|stripslashes}{/if}" class="account_input" /></p>

<p><input type="image" name="SubmitCreate" src="{$img_dir}{$lang_iso}/btn-create-account.gif" /></p>

</form>

</div>

<div class="login">

<form action="{$request_uri}" method="post">

<h2 class="auth">{l s='Already registered ?'}</h2>

<div class="form_field_header">{l s='Enter your e-mail address and password to access to your account'}.</div>

<div>{l s='E-mail address'}</div>

<p><input type="text" name="email" value="{if isset($smarty.post.email)}{$smarty.post.email|escape:'htmlall'|stripslashes}{/if}" class="account_input" /></p>

<p><span class="form_field_header">{l s='Password'}</span></p>

<p><input type="password" name="passwd" value="{if isset($smarty.post.passwd)}{$smarty.post.passwd|escape:'htmlall'|stripslashes}{/if}" class="account_input" /></p>

<p><input type="image" name="SubmitLogin" src="{$img_dir}{$lang_iso}/btn-login.gif" /></p>

<p> </p>

<p><a href="password.php">{l s='Forgot your password?'}</a>

<a href="password.php"><img src="{$img_dir}arrow.gif" alt=">" title=">" class="text-top" /></a></p>

{if $back}<p><input type="hidden" name="back" value="{$back}" /></p>{/if}

</form>

</div>

{else}

<form action="{$request_uri}" method="post">

<fieldset class="account_creation">

<legend>{l s='Your personal information'}</legend>

<p><label>{l s='First name'}</label></p>

<div class="margin-form">

<p><input onkeyup="getE('surname').value = this.value;" type="text" name="customer_surname" value="{if isset($smarty.post.customer_surname)}{$smarty.post.customer_surname|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Last name'}</label></p>

<div class="margin-form">

<p><input onkeyup="getE('name').value = this.value;" type="text" name="customer_name" value="{if isset($smarty.post.customer_name)}{$smarty.post.customer_name|escape:'htmlall,UTF-8'|stripslashes}{/if}" style="text-transform: uppercase;" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='E-mail'}</label></p>

<div class="margin-form">

<p><input type="text" name="email" value="{if isset($smarty.post.email)}{$smarty.post.email|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Password'}</label></p>

<div class="margin-form">

<p><input type="password" name="passwd" /> <sup class="red_star">*</sup> {l s='(5 characters min.)'}</p>

</div>

<div class="clear"></div>

<p><label>{l s='Gender'}</label></p>

<div class="margin-form">

<p><input type="radio" name="id_gender" class="icon" value="1" {if !isset($smarty.post.id_gender) OR $smarty.post.id_gender == 1}checked="checked"{/if} />

<img src="{$img_dir}male.gif" class="icon" alt="{l s='Male'}" title="{l s='Male'}" />

<input type="radio" name="id_gender" class="icon" value="2" {if isset($smarty.post.id_gender) && $smarty.post.id_gender == 2}checked="checked"{/if} />

<img src="{$img_dir}female.gif" class="icon" alt="{l s='Female'}" title="{l s='Female'}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Birthday'}</label></p>

<div class="margin-form">

<select name="days">{$days}</select>

<select name="months">{$months}</select>

<select name="years">{$years}</select>

</div>

<div class="clear"></div>

<div class="margin-form">

<p><input type="checkbox" name="newsletter" id="newsletter" value="1" {if isset($smarty.post.newsletter) AND $smarty.post.newsletter == 1} checked="checked"{/if} />

<label for="newsletter" class="label-checkbox">{l s='Register to our newsletter'}</label></p>

</div>

<div class="clear"></div>

<div class="margin-form">

<p><input type="checkbox" name="optin" id="optin" value="1" {if isset($smarty.post.optin) AND $smarty.post.optin == 1} checked="checked"{/if} />

<label for="optin" class="label-checkbox">{l s='Receive special offers from our partners'}</label></p>

</div>

<div class="clear"></div>

</fieldset>

<fieldset class="account_creation">

<legend>{l s='Your address'}</legend>

<p><label>{l s='Company'}</label></p>

<div class="margin-form">

<p><input type="text" name="company" value="{if isset($smarty.post.company)}{$smarty.post.company|escape:'htmlall,UTF-8'|stripslashes}{/if}" /></p>

</div>

<div class="clear"></div>

<p><label>{l s='First name'}</label></p>

<div class="margin-form">

<p><input type="text" id="surname" name="surname" value="{if isset($smarty.post.surname)}{$smarty.post.surname|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Last name'}</label></p>

<div class="margin-form">

<p><input type="text" id="name" name="name" value="{if isset($smarty.post.name)}{$smarty.post.name|escape:'htmlall,UTF-8'|stripslashes}{/if}" style="text-transform: uppercase;" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Address'}</label></p>

<div class="margin-form">

<p><input type="text" name="address1" size="42" value="{if isset($smarty.post.address1)}{$smarty.post.address1|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Address (2)'}</label></p>

<div class="margin-form">

<p><input type="text" name="address2" size="42" value="{if isset($smarty.post.address2)}{$smarty.post.address2|escape:'htmlall,UTF-8'|stripslashes}{/if}" /></p>

</div>

<div class="clear"></div>

<p><label>{l s='Postal code / Zip code'}</label></p>

<div class="margin-form">

<p><input type="text" name="postcode" value="{if isset($smarty.post.postcode)}{$smarty.post.postcode|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='City'}</label></p>

<div class="margin-form">

<p><input type="text" name="city"  value="{if isset($smarty.post.city)}{$smarty.post.city|escape:'htmlall,UTF-8'|stripslashes}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

<p><label>{l s='Country'}</label></p>

<div class="margin-form">

<select name="id_country">{$countries_list}</select> <sup class="red_star">*</sup>

</div>

<div class="clear"></div>

<p><label>{l s='Additional information'}</label></p>

<div class="margin-form">

<p><textarea name="other" cols="26" rows="3">{if isset($smarty.post.other)}{$smarty.post.other|escape:'htmlall,UTF-8'|stripslashes}{/if}</textarea></p>

</div>

<div class="clear"></div>

<p><label>{l s='Home phone'}</label></p>

<div class="margin-form">

<p><input type="text" name="phone" value="{if isset($smarty.post.phone)}{$smarty.post.phone|escape:'htmlall,UTF-8'|stripslashes}{/if}" /></p>

</div>

<div class="clear"></div>

<p><label>{l s='Mobile phone'}</label></p>

<div class="margin-form">

<p><input type="text" name="phone_mobile" value="{if isset($smarty.post.phone_mobile)}{$smarty.post.phone_mobile|escape:'htmlall,UTF-8'|stripslashes}{/if}" /></p>

</div>

<div class="clear"></div>

<p><label>{l s='Assign an address title for future reference'} !</label></p>

<div class="margin-form">

<p><input type="text" name="alias" value="{if isset($smarty.post.alias)}{$smarty.post.alias|escape:'htmlall,UTF-8'|stripslashes}{else}{l s='My address'}{/if}" /> <sup class="red_star">*</sup></p>

</div>

<div class="clear"></div>

</fieldset>

<p><sup class="red_star">*</sup> {l s='Required field'}</p>

<div class="center space">

<p><input type="submit" name="submitAccount" value="{l s='Register'}" /></p>

</div>

<p><input type="hidden" name="email_create" value="1" /></p>

</form>

{/if}

{/if}

[/pre]

 

Un léger correctif de la feuille de styles permet d'améliorer la présentation

 

Fichier /root/modeles/default/css/styles.css :

 

(# line 1591)

 

[pre]/* Account creation */

fieldset.account_creation {

width: auto;

margin-top: 20px;

}

fieldset.account_creation .margin-form p img{cursor:help}[/pre]

 

On obtient une page valide xhtml Strict 1.0. (dès lors que l'on utilise le doctype document approprié ;) )

 

Cordialement,

 

 

Link to comment
Share on other sites

  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...