IT related news, fotography, fun and webdevelopment
14 jun
Dutch
Het probleem
Na het upgraden van Magento naar versie 1.4.0.1 was er een klein probleem met het doorsturen naar de startpagina in de backoffice.
Na iedere keer inloggen resulteerde dit in een 404 pagina.
Omdat ik het niet in elke webshop had, ben ik opzoek gegaan naar het probleem.
Het probleem is het toevoegen van de winkelcode aan de URL, bij een meertalige webshop is dit voor SEO een must zodat je bijvoorbeeld URL’s als www.voorbeeldschop.nl/nl/categorie/product.html krijgt. Hierdoor kan je unieke URL’s per land uitserveren.
Echter worden deze codes ook in het admin gedeelte (de backoffice) gebruikt, standaard is hier de ‘storecode’ admin.
Omdat het backoffice standaard is te benaderen via www.voorbeeldschop.nl/admin en hier nog de storecode aan moet worden toegevoegd, krijg je feitelijk dus www.voorbeeldschop.nl/admin/admin/.
De oplossing
Omdat in het inlog formulier geen HTML action staat, zal het formulier de huidige URL gebruiken, als u de backoffice dus benaderd zonder extra storecode, maar wel deze instelling aan heeft staan, (dit is trouwens hier in te stellen: System->Configuration->General->Store Code to URLs), zal het formulier naar de verkeerde URL gaan, namelijk de versie zonder store code.
Wil je wel de backoffice kunnen benaderen zonder www.voorbeelshop.nl/admin/admin te moeten gebruiken, pas dan het volgende aan:
app/design/adminhtml/{theme}/{template}/template/login.phtml on linenumber 48
<form method="post" action="" id="loginForm">;
Vervang met:
<form method="post" action="http://<?php echo $_SERVER['HTTP_HOST']; ?>/admin/admin/" id="loginForm">
Let op
Gebruikt u een aangepaste admin-URL dan doet u deze op te geven i.p.v. ‘admin’.
English
The problem
After upgrading to 1.4.0.1 Magento we had a 404 after each login action.
Because I do not have this issue by any shop, I started looking for a solution.
The problem is due to the “Add Store Code to URL” setting.
It adds the storecode to the URL.
This storecode is also expected in the admin area.
By default, the login form called via (domain) / admin and no action on the form is passed, thus there is no known storecode.
The solution
Als je het inlogformulier aanroep via {domein}/admin/admin zal het werken.
If you also want (domain) / admin work, change the following:
app/design/adminhtml/{theme}/{template}/template/login.phtml on linenumber 48
<form method="post" action="" id="loginForm">
Replace with:
<form method="post" action="http://<?php echo $_SERVER['HTTP_HOST']; ?>/admin/admin/" id="loginForm">
15 sep
In mijn vorige tutorial beschreef ik het toevoegen van extra registratie velden bij een bestelling of klant registratie.
Er van uitgaand dat dit gelukt is, kan ik me voorstellen dat je nu tegen het validatie probleem aanloopt.
In dit artikel zal ik de validatie van de gegevens voor de checkout beschrijven.
Dit is dus bij het afronden van een bestelling, voor niet geregistreerde (nieuwe) klanten
In dit voorbeeld maak ik van telefoonnummer een niet verplicht veld.
Om te beginnen moet je zorgen dat de Javascript validatie niet reageert op dit attribute (op telefoonnummer) ga hiervoor naar de juiste view.
Standaard is dit app/design/frontend/{thema}/{template}/template/checkout/onepage/billing.phtml
Standaard zul je hier dit zien:
<li> <div class="input-box"> <label for="billing:telephone">< ?php echo $this->__('Telephone') ?> <span class="required">*</span></label><br /> <input type="text" name="billing[telephone]" value="<?php echo $this-/>htmlEscape($this->getAddress()->getTelephone()) ?>" title="< ?php echo $this->__('Telephone') ?>" class="required-entry input-text" id="billing:telephone" /> </div> <em> verdere code is achterwege gelaten.</em>
Om te zorgen dat de Javascript validatie telefoonnummer niet meer als verplicht attribute behandeld, hoef je slechts de CSS class ‘required-entry’ te verwijderen.
Je krijgt dus dit:
class="input-text" i.p.v. class="required-entry input-text"
Nu zal Magento bij het afronden van deze stap (en de bestelling) echter nog altijd melden dat telefoonnummer verplicht is.
Dit komt doordat het ajax-request naar de model Mage_Sales_Model_Quote_Address gaat, deze klasse erft op zijn beurt weer over van Mage_Customer_Model_Address_Abstract. De laatst genoemde heeft een public function validate, welke verantwoordelijk is voor de validatie.
Echter is het roekeloos aanpassen van deze model een slecht idee, aangezien je dat in de Mage_Core aan het aanpassen bent, zul je bij updates van Magento mogelijk in de problemen komen. Hiervoor moet je dus de chill-klasse overerven en deze van nieuwe logica (een nieuwe validate functie) voorzien.
Het extenden van een bestaande core class wordt in een eerder artikel al uitgelegd maar hier toch nog even in het kort.
Maak een eigen module en brengt Magento hiervan op de hoogte middels een xml config bestand.
/** * @desc Override the validate function * @author Johan van de Pol * @version 0.1.0 * * @category ACSI * @package ACSI_Global * @copyright Copyright (c) 2009 Johan van de Pol * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class ACSI_Global_Sales_Model_Quote_Address extends Mage_Sales_Model_Quote_Address { /** * Validate address attribute values * * @return Mixed | Bool (true by no errors) | Array (With error messages by errors) */ public function validate() { $errors = array(); $helper = Mage::helper('customer'); $this->implodeStreetAddress(); if (!Zend_Validate::is($this->getFirstname(), 'NotEmpty')) { $errors[] = $helper->__('Please enter first name.'); } if (!Zend_Validate::is($this->getLastname(), 'NotEmpty')) { $errors[] = $helper->__('Please enter last name.'); } if (!Zend_Validate::is($this->getStreet(1), 'NotEmpty')) { $errors[] = $helper->__('Please enter street.'); } if (!Zend_Validate::is($this->getCity(), 'NotEmpty')) { $errors[] = $helper->__('Please enter city.'); } if (!Zend_Validate::is($this->getTelephone(), 'NotEmpty')) { $errors[] = $helper->__('Please enter telephone.'); } if (!Zend_Validate::is($this->getPostcode(), 'NotEmpty')) { $errors[] = $helper->__('Please enter zip/postal code.'); } if (!Zend_Validate::is($this->getRegion(), 'NotEmpty')) { $errors[] = $helper->__('Please enter region.'); } if (!Zend_Validate::is($this->getCountryId(), 'NotEmpty')) { $errors[] = $helper->__('Please enter country.'); } if ($this->getCountryModel()->getRegionCollection()->getSize() && !Zend_Validate::is($this->getRegionId(), 'NotEmpty')) { $errors[] = $helper->__('Please enter state/province.'); } if (empty($errors)) { return >true; } return $errors; //Eventueel orignele functie nog aanroepen //parent::validate(); } }
In je eigen validate functie moet je uiteraard de validatie van de telefoon verwijderen dus
if (!Zend_Validate::is($this->getTelephone(), ‘NotEmpty’)) {
etc. moet weg.
Wellicht ten overvloede, maar in de config van je module moet uiteraard wel het volgende staan:
< ?xml version="1.0"?> <config> <global> <sales> <rewrite> <quote_address>ACSI_Global_Sales_Model_Quote_Address</quote_address> </rewrite> </sales> </global> </config>
Op deze manier zorgt Magento ervoor dat jou klasse wordt aangeroepen i.p.v. het origineel, door hem te extenden blijft de verdere functionaliteit gewaarborgd en kan je makkelijk functies herschrijven, in dit voorbeeld hebben we een parent functie herschreven.
Met deze kennis is het mogelijk om alle afwijkende attributen te valideren en te tonen etc.
Maar mocht het standaard pakket voldoende zijn en wil je slechts hiervoor validatie hebben, dan volstaat deze extensie:
Deze extensie werkt overigens op nagenoeg dezelfde manier.
Vergeet overigens niet de mappen app/design/frontend/default/thema/layout/dull/ en
app/design/frontend/default/thema/template/dull/ te kopiëren naar je eigen template/thema.
Mochten er vragen zijn, contact op nemen kan altijd: magento at johanvandepol dot nl
Deze tutorial is geschreven op het moment dat Magento 1.3.2.3 de meest recente versie was.
5 aug
Vaak is het gewenst om extra velden toe te voegen aan de klant-registratie (Customer_Block_Form_Register). Hier zijn een aantal stappen voor nodig:
1.) Installeer de ‘Attributes manager’: Magento Connect – Attributes manager – Overview – eCommerce Software for Growth
2.) Fix de URL’s van deze extensie in de BackOffice.
Ga hiervoor naar: “app/design/adminhtml/{template}/template/attributemanager/index.phtml”
En fix de a href’s met de volgende code:
<div align="center"> <h3 class="icon-head"><u>< ?php echo Mage::helper('attributemanager')->__('Choose attributes to manage') ?></u></h3> <br /><br /> <h3 class="icon-head"> <a href="<?php echo $this->getUrl('*/*/category');?>">< ?php echo Mage::helper('attributemanager')->__('Categories attributes') ?></a> <br /> <a href="<?php echo $this->getUrl('*/*/customer');?>">< ?php echo Mage::helper('attributemanager')->__('Customers attributes') ?></a> <br /> <a href="<?php echo $this->getUrl('*/*/address');?>">< ?php echo Mage::helper('attributemanager')->__('Customers address attributes') ?></a></h3> </div>
3.) Maak je custom attribute (extra invoer veld). Bijvoorbeeld extra veld bij de klant registratie (customer registration).
Dit kunt u hier doen: admin/Systeem/Manager/Manage attributes
De attribute manager zorgt ervoor dat het custom attribute in de tabel eav_attribute wordt geplaatst.
4.) We moeten de core klasse Mage_Customer_Block_Form_Register uitbreiden met wat functionaliteit.
Aangezien we bij een update ook operationeel willen blijven, moeten we magento hier uitbreiden, we attenderen Magento op onze extra functionaliteit. Let op De stap is alleen nodig bij het dynamisch ophalen van drop-down lijsten, voor een simpel invoer veld is deze functie niet nodig
Maak een file {BedrijfsNaam}_Customer.xml in: app/etc/modules/ en voeg hier de volgende XML code aan toe.
< ?xml version="1.0"?> <config> <modules> <bedrijfsnaam_customer> <active>true</active> <codepool>local</codepool> <version>>0.1.0< /span></version> </bedrijfsnaam_customer> </modules> </config>
Nu weet Magento dat hij eerst bij de door jou zelf gedefineerde module moet kijken.
Maar nu moeten we deze klasse nog wel even maken uiteraard.
Maak dit bestand aan:
app/code/local/{BedrijfsNaam}/Customer/Block/Form/Register.php
Let op
Extra zelf gedefineerde code, moet je altijd in de map app/code/local/ plaatsen, deze code wordt bij een update van Magento niet overschreven.
Hier de klasse zelf (de Register.php):
< ?php /** * Customer register form block * * @author Johan van de Pol */ class BedrijfsNaam_Customer_Block_Form_Register extends Mage_Customer_Block_Form_Register { /** * Get CustomField options * * @param String $custom_field Name of custom_field. * @param Integer $attribute_id Attribute_ID of custom field. * @return Array With attribute options. */ public function getCustomFieldOption ($custom_field, $attribute_id) { $attribute = Mage::getModel('customer/customer')->getAttribute($custom_field, $attribute_id); return $attribute->getSource()->getAllOptions(true, true); } }
Voor de afhandeling moet magento er ook op worden geattendeerd dat er een extra attribute bij gekomen is (voor de afhandeling en het opslaan). En hij moet weten dat de klasse van jou module eerst moet worden aangeroepen.
Maak hiervoor het volgende bestand aan:
app/code/local/{BedrijfsNaam}/Customer/etc/config.xml
< ?xml version="1.0"?> <config> <global> <blocks> <customer> <rewrite> <form_register>BedrijfsNaam_Customer_Block_Form_Register</form_register> </rewrite> </customer> </blocks> <fieldsets> <customer_account> <extra_veld><create>>1< /span></create></extra_veld> </customer_account> </fieldsets> </global> </config>
5.) Nu is het tijd voor de weergave van het drop-down attribute zelf.
Zet hiervoor onderstaande code in app/design/frontend/{template}template/customer/form/register.phtml
<div class="input-box"> <label for="UW_EXTRA_VELD">< ?php echo $this->__('UW_EXTRA_VELD') ?><span class="required">*</span></label><br /> <select id="UW_EXTRA_VELD" name="UW_EXTRA_VELD" class="select"> < ?php foreach ($this->getCustomFieldOption('UW_EXTRA_VELD', 'attribute_id') as $option): ?> <option value="<?php echo $option['value'] ?>">< ?php echo $option['label'] ?></option> < ?php endforeach; ?> </select> </div>
Opmerking
Zonder attribute_id werkt hij blijkbaar ook, maar het attribute ID vind je in de database en wel in de volgende tabel ‘eav_attribute’.
De volgende Query levert u het juiste attributeID op:
SELECT attribute_id FROM `eav_attribute` WHERE `attribute_code` = 'UW_EXTRA_VELD'
Het extra attribute (input field or dropdown list) is nu zichtbaar en wordt ook netjes opgeslagen.
Deze tutorial is geschreven op het moment dat Magento 1.3.2.3 de meest recente versie was.
23 jul
De bug in firebug 1.4 ook zo zat? installeer de meest recente versie (firebug-1.5X.0a18) op http://getfirebug.com/releases/firebug/1.5X/
De bug in versie 1.4 zorgt er voor dat ongeveer 3 op de 10 ajax requests (xmlhttprequest) falen, dit is natuurlijk erg irritant.
De foutmelding die getoond wordt is overigens:
onreadystatechange FAILS Error: Permission denied for <http://localhost> to create wrapper for object of class UnnamedClass Error: Permission denied for <http://localhost> to create wrapper for object of class UnnamedClass readystatechange
16 jul
Waar veel webontwikkelaars al mee bezig waren, gaan de grote bedrijven nu ook mee beginnen. We hebben het dan over het niet meer ondersteunen van Internet Explorer 6.0.
Aangezien dat deze browser zich erg slecht hield aan de W3C standaard, was het altijd een ware plaag voor de webdeveloper.
YouTube
Met het grote bedrijf doel ik op Google, die de ondersteuning van IE 6.0 niet meer biedt bij haar project Youtube. Zoals te lezen is op Nu.nl zegt YouTube IE 6.0 voorgoed vaarwel.
Gebruik
Toch wordt IE 6.0 nog opmerkelijk veel gebruikt, dit komt vooral door het achterblijven van sommige bedrijven. Privé wordt IE 6.0 nog maar op hele kleine schaal gebruikt. Zie ook:
| 2009 | IE7 | IE6 | IE8 | Firefox | Chrome | Safari | Opera |
|---|---|---|---|---|---|---|---|
| June | 18.7% | 14.9% | 7.1% | 47.3% | 6.0% | 3.1% | 2.1% |
| May | 21.3% | 14.5% | 5.2% | 47.7% | 5.5% | 3.0% | 2.2% |
| April | 23.2% | 15.4% | 3.5% | 47.1% | 4.9% | 3.0% | 2.2% |
| March | 24.9% | 17.0% | 1.4% | 46.5% | 4.2% | 3.1% | 2.3% |
| February | 25.4% | 17.4% | 0.8% | 46.4% | 4.0% | 3.0% | 2.2% |
| January | 25.7% | 18.5% | 0.6% | 45.5% | 3.9% | 3.0% | 2.3% |
Bron: w3schools
5 mei
Met Google Analytics kan je de bezoekers van je site analyseren. De meeste internet bedrijven gebruiken deze tool dan ook veelvuldig. Zelf gebruik ik Google Analytics ook voor de meeste projecten, zo ook voor devrijetrappers.nl.

Illustratie van bezoekers per dag
Devrijetrappers.nl is een site van een zaalvoetbalvereniging, de kern van de activiteiten van de bezoekers ligt natuurlijk op het kijken hoe laat er gespeeld moet worden. Nu is het zo dat Google Analytics dit erg mooi illustreert. (zie afbeelding).
De bezoekers van deze website zijn natuurlijk maar in 1 ding echt geïnteresseerd en dat is hoe laat moeten we spelen? Wanneer deze interesse gewekt wordt, is natuurlijk ook duidelijk aangezien woensdagavond de enige speelavond is. Op de afbeelding zie je precies dat elke woensdag een piek moment is in de bezoekersaantallen.