duminică, 21 noiembrie 2010

Building a Simple CSS Selector Engine: New Premium Tutorial

 Recently, I thought I’d try my hand at creating a simple CSS selector engine. You know what I’m talking about: it’s the kind of thing you use in most JavaScript libraries, where you pass in a CSS selector to find the elements you want to work with. Today, I’ll show you how to create a really simple one!

Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts.




You’ve probably used the selector engines built into several JavaScript libraries, but do you have any idea how they’re built?


If not, this tutorial will take you through the process of crafting your own CSS selector engine. You’ll learn how to break down the decently complex problem of selecting DOM elements into manageable chunks and code it piece by piece . . . all while using only the best JavaScript practices!“


For those unfamiliar, the family of Tuts+ sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Phototuts+, Aetuts+, Audiotuts+, Vectortuts+, and CgTuts+ For the price of a pizza, you’ll learn from some of the best minds in the business. Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts.


View the original article here


If you're looking for simple and effective ways to influence you, your results and the world, you'll find powerful tools here from an official UK number 1 trainer and coach. Enjoy and be impeccable!


Check it out!

SWISSGENTO 1.0

On November 22, Geneva will be hosting the first Swissgento!


Join the Swiss and French community and get ready to meet all local major Magento experts . The one-day event will take place at the Convention Center – Ramada Hôtel - Geneva. Admission is free and you can expect to see more than 17 exhibitors, 14 presentations, and meet Michel Goossens, VP & GM of Magento’s EMEA Operations. Register online now! It’s free!


Whether you already use Magento or intend to migrate to this solution, your visit to Swissgento will provide all the answers on the most popular eCommerce solution in the world. For more information or to read about this event in French, please visit the conference website.


View the original article here


If you're looking for simple and effective ways to influence you, your results and the world, you'll find powerful tools here from an official UK number 1 trainer and coach. Enjoy and be impeccable!


Check it out!

Why are you switching to Magento?

“Hello! I run an online store for a few years. It was developed in osCommerce originally and that’s why the sales suck. I would like you guys to move my shop to Magento. I heard a lot of good things about it and I’m sure that once we move there, our sales will skyrocket.” This is simplified version of a talk I had few days ago.

osCommerce is outdated. If this business owner wishes to continue his eCommerce business in next few years, it is true that it would be a good idea to replace osCommerce with a solution that has cleaner future. It does not have to be Magento. However, this was not the reason why he wished to move away. He believed that Magento itself will boost his sales since “everyone talks about it”.


Here in Inchoo, web design and development services bring food to the table. Since this guy was asking for web development services and he had fine budget, it would be logical thing to close a deal and start the work. However, his expectations were obviously wrong. If we would have accepted this project, we would deliver it in time and charge him the cost. Everything would be fine to the point where site would be live for two weeks and his sales would still be low as in his osCommerce store.


If your eCommerce business is not performing well as you were hoping for, do not think that platform change is an instant solution. It might help if played right, but there are some things you need to reevaluate first:

Are your products interesting to the market? Maybe they were few years ago when the sales were good and competition rarer, but are they now?What are competitors doing? Are there more online stores that sell similar products? Are they better than you? What are they doing that you do not?Are your prices competitive? Like in every business, lowering the prices should be the last method to use, but in case all the competition has lower prices for similar products, you might want to experiment a little.Are you marketing your store efficiently? Back in 2004 when you launched your store, Google organic visits might have been generating 90% of your sales. Did things change? Did the behavior of your customers change?

After you reevaluate your business and when you are sure that the poor sales are caused by a solution you have, ancient and confusing design, bugs in the system, poor security, slow hosting or something more, it is the time to address solution partner. Before you make a contact, be clear with yourself what is your product, your market and why are you better than competition. When you know this, our work can shine. If you don’t know those 3 answers, all we can offer is work. Not a success.


To post code in comments, place your code inside [code] and [/code] tags.


View the original article here


If you're looking for simple and effective ways to influence you, your results and the world, you'll find powerful tools here from an official UK number 1 trainer and coach. Enjoy and be impeccable!


Check it out!

Online Book Shops Powered by Magento

Earlier this week we reviewed Book Store Magento Templates and now we’d like to showcase the online book shops that are powered by the Magento ecommerce software. Please keep in mind; we’ll list only the most beautiful eCommerce sites we could find on the web because our aim is to inspire you in every way we can.


Here you’ll find 12 Magento sites selling books, magazines, maps and posters. Although, all sites are unique and were created in different countries, they offer similar products and services.


So, take a few minutes to see the most impressive online book shops that were built with Magento and if you need some ready-to-use solutions, then check out our article about the Book Shop Magento Templates.


totallybooks.com.au


webshop.inspirerendleven.nl


livrariaupstage.com


matthiasmedia.com.au


shop.timeout.com


csestore.cse.org.in


businessmall.com.au


poster.com


map-sales.com


mk1.co.nz


modellearningshop.com


waanders.nl


View the original article here


If you're looking for simple and effective ways to influence you, your results and the world, you'll find powerful tools here from an official UK number 1 trainer and coach. Enjoy and be impeccable!


Check it out!

Tonys Coffee Shop Business Plan

Business plan to open a coffee shop, written by an experienced shop owner, worker and entrepreneur. Includes many bonuses and extras including email and personal consult.

Check it out!

Using A Backend Model To Customize Magento (A Tip From Magento Developers Paradise)

This is a tip from Vitaly Korotun in his presentation at the Magento Developers Paradise on using custom backend models to customize Magento. I thought I’d expand on his tip with a worked example for my own benefit – but you may find it useful too!


I think this was a bit of an Aha! moment at the conference as everyone in the room gave sideways looks to Vitaly’s answer to his own question: “How would we implement custom functionality to integrate with a third party system every time product data changes”. I thought I already knew the answer, or at least all of the possible answers. But Vitaly had a good one, that I didn’t think of.


You can see the answers on slide 40/43 of the presentation. Here are my thoughts on each, the last one is the one I hadn’t thought of, and judging by the ajar mouths in the conference room, a lot of other developers hadn’t thought of it either!

Override the controller saveAction()

This is not a very good solution as it will only run the customized functionality when the model is saved from the controller (through the browser for example). It wouldn’t run if the model was saved from the API though which in most cases will be a problem. This might be a suitable solution if it is desirable functionality for the 3rd party update to only occur when the model is updated from through the controller though, so consider it an option in some cases for very specific requirements.

Override the Product model save() method (or the resource model save)

This is probably the most common solution, override the model and implement functionality in the save method. It works no matter how the object is saved, but is open to extension clash hell which is not appealing.
(I’ve grouped these two together, because they’re mostly the same)

Declare an Observer for the save event

This is one of the solutions I suggested in my own presentation when using extensions for customized functionality that avoids clashes. It can help to avoid the clash issues and allows pinpoint customizing with eitherbeforeSave or afterSave events. So a great solution for the problem posed by Vitaly and the one I think most developers, myself included, considered the best.

Using a custom backend model for an attribute.

Vitaly suggested using a customized backend model for a particular product attribute as the solution. This was a new one to me, though in hindsight I see it’s a technique already in use in a number of places in Magento core code, I’d just not noticed until someone pointed out the obvious. I’ll look at this technique in more detail below, following it up with a worked example.


There are a number of benefits with the solution of a custom backend model on an attribute. It means the custom functionality exists at the attribute level. As we know attributes can be added/removed from products easily in Magento. That means to apply the 3rd party integration on all products of a particular type, we would simply add the attribute to the attribute set for that type of product. This gives us the flexibility to integrate only for certain product types too.


This sort of flexibility to add the attribute onto only some products can be really useful. For example, if a store sold Digital cameras and SD cards, then perhaps they’d only put the audit_check attribute on the digital camera attribute set, so only when digital cameras are being modified will an email get sent to the manager to audit the changes (perhaps they don’t care who changes the price of SD cards).


It’s also less prone to clashes as even if someone else is overriding the save functionality or listening for the event, they won’t affect the save function of your attribute. Particularly on a model as central as the Product.


One of the hassles is it requires that the attribute be added to the product’s attribute set in order to function. This can be done manually by the store owner in the admin interface, or in a script from within your extension. If you specify the attribute is a system attribute when you create it, then it will be automatically added to all attribute sets in the system, and the attribute cannot be removed via the admin interface (nor can it be deleted). We’ll look at how this can be done in the next section.


For this example we’ll create an attribute that when applied to a product, will cause any changes made to that product to be logged for audit. This allows a store manager to keep a tabs on what products are being changed and in what ways, for any attribute sets which contain the audit_check attribute. Update: this is now an actual extension – if you want to see a working example.


First we define the attribute and decide if the logic should run beforeSave or afterSave. Here’s a trivial example of an afterSave backend model.

class Aschroder_ProductAudit_Model_Entity_Attribute_Backend_Audit extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract { public function afterSave($object) {// This is where we would perform the audit (or any other logic we wanted)// We could email the changes to a store admin, for example }}

Now we need to install the attribute and decide if it should be a system attribute or not. There are a few steps involved here. If you need a full tutorial on creating setup scripts for your extensions, check out Alan Storm’s excellent guide. I’ll assume you know that and won’t explain it again here. (One word of warning: Do make sure your setup is a subclass of Mage_Eav_Model_Entity_Setup)


Adding a system attribute


Adding a system attribute will ensure the attribute is added to all sets in the system, and that it cannot be removed.

// This attribute will get installed in all attribute sets$installer->addAttribute('catalog_product', 'audit_check',array( 'type' => 'varchar', 'label' => 'Reason for Change', 'class' => '', 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE, 'backend'=> 'productaudit/entity_attribute_backend_audit', 'visible' => true, 'required' => true, 'user_defined' => false, // this is what determines if it will be a system attribute or not 'default' => '', 'searchable' => false, 'filterable' => false, 'comparable' => false, 'visible_on_front' => false, 'unique' => false ));

If you want to see how this system attribute is applied to all sets, check out function addAttribute in Mage_Eav_Model_Entity_Setup. You’ll notice this little snippet which adds the attribute to all the sets:

if (empty($attr['user_defined'])) { $sets = $this->_conn->fetchAll('select * from '.$this->getTable('eav/attribute_set').' where entity_type_id=?', $entityTypeId); foreach ($sets as $set) { $this->addAttributeToSet($entityTypeId, $set['attribute_set_id'], $this->_generalGroupName, $code, $sortOrder); }}

Note: If you’re like me, you might develop a slight nervous twitch when you see PHP code that uses the empty() function to test if something is true or false (false is hardly empty, it’s false, right?) – apparently it’s totally kosher, relax!


You can also use the ‘group‘ property on the attribute to assign the attribute to a particular group for every attribute set (and add the group).


Adding a non-system attribute
Non-system attributes will not be added to any attribute sets by default. However you can add them to sets manually or automatically as in the next section.


The only difference is the setting of user_defined to true like so:

// This attribute will get installed in no attribute sets by default$installer->addAttribute('catalog_product', 'audit_check_non_system',array( 'type' => 'varchar', 'label' => 'Reason for Change', 'class' => '', 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE, 'backend'=> 'productaudit/entity_attribute_backend_audit', 'visible' => true, 'required' => true, 'user_defined' => true, // this is what determines if it will be a system attribute or not 'default' => '', 'searchable' => false, 'filterable' => false, 'comparable' => false, 'visible_on_front' => false, 'unique' => false ));

If you chose to make the attribute user defined (i.e non-system) in the previous section, then you either have to add it to an attribute set from within your script, or the store admin would have to do so manually from within the admin interface. Otherwise, it’s just an attribute floating in space, not associated to any product. Let’s look at both of these options:


Adding the attribute to a set in your script


When you create a non-system attribute you’ll have to add it to a set automatically. You can optionally create your own group automatically too.

// Add a new group (these are the sections in the admin interface)// You can just use General - in which case you do not need to add a new group$installer->addAttributeGroup('catalog_product', 'Default', 'Audit');//Add the attribute to the group (implicitly adds it to the set too)$installer->addAttributeToGroup ('catalog_product', 'Default', 'Audit', 'audit_check_non_system');

The result will look like this in the attribute set admin screen:



And like this when editing a product in the Default attribute set:



Adding the attribute to a set from within the admin interface


If you add the attribute as part of your customizations but then do not assign it to a set, it allows store managers to choose which attribute sets use the attribute. This is done through the Catalog->Attributes->Manage Attribute Sets menu, you simple drag and drop the attribute onto your desired group, Easy eh!


It’s a bit of a cop-out I know, but I’m going to say that all of the solutions have their strengths and weaknesses, you should use the solution that best solves the problem at hand. In the most part, the overriding of a model or listening for an event will be easy, and fairly safe. It’s nice to know there is another option available to us though. It takes a fair bit more work to implement, but gives a flexible solution – thanks to Vitaly for sharing it.


View the original article here


Business plan to open a coffee shop, written by an experienced shop owner, worker and entrepreneur. Includes many bonuses and extras including email and personal consult.


Check it out!


 

sâmbătă, 20 noiembrie 2010

Quick Tip: Detect CSS3 Support in Browsers with JavaScript

Isn’t it fun that we get to play with the latest CSS techniques, like shadows and transitions? There’s only one problem: how do we compensate, or more importantly, detect the browsers that do not support them? Well, there’s a few solutions. In this tutorial and screencast, though, we’ll create a JavaScript function that will accept a CSS property name as its parameter, and will return a boolean, indicating whether or not the browser supports the passed property.


Let’s begin by determining how we want to call our function. We’ll keep things simple here; something like the following should do the trick:

if ( supports('textShadow') ) { document.documentElement.className += ' textShadow';}

That should be the final function call. When we pass a CSS property name to the supports() function, it’ll return a boolean. If true, we’ll attach a className to the documentElement, or . This will then provide us with a new `class` name to hook onto, from our stylesheet.


Next, we’ll construct the supports() function.

var supports = (function() {})();

Why aren’t we making supports equal to a standard function? The answer is because we have a bit of prep work to do first, and there’s absolutely no reason to repeat those tasks over and over every single time the function is called. In cases like this, it’s best to make supports equal to whatever is returned from the self-executing function.


To test whether or not the browser supports specific properties, we need to create a *dummy* element, for testing. This generated element will never actually be inserted into the DOM; think of it as a test dummy!

var div = document.createElement('div');

As you’re probably aware of, there are a handful of vendor-prefixes that we can use, when working with CSS3 properties:


Our JavaScript will need to filter through those prefixes, and test them. So, let’s place them in an array; we’ll call it, vendors.

var div = document.createElement('div'), vendors = 'Khtml Ms O Moz Webkit'.split(' ');

Using the split() function to create an array from a string is admittedly lazy, but it saves a handful of seconds!


As we’ll be filtering through this array, let’s be good boys and girls, and cache the length of the array as well.

var div = document.createElement('div'), vendors = 'Khtml Ms O Moz Webkit'.split(' '), len = vendors.length;

The prep work, above, is static, in nature, and doesn’t need to be repeated every time we call supports(). This is why we only run it once, when the page loads. Now, let’s return the function that will actually be assigned to the supports variable.

return function(prop) {};

The beauty of closures is that, even though supports() is equal to that returned function, it still has access to the div, vendors, and len variables.


The immediate test: if the passed property is available to the div‘s style attribute, we know the browser supports the property; so return true.

return function(prop) { if ( prop in div.style ) return true;};

Think of, say, the text-shadow CSS3 property. Most modern browsers support it, without the need for a vendor prefix. With that in mind, why filter through all of the prefixes if we don’t need to? That’s why we place this check at the top.


You’re likely used to typing CSS3 property names, like so: -moz-box-shadow. However, if, in Firebug, you review the style object, you’ll find that it’s spelled, MozBoxShadow. As such, if we test:

'mozboxShadow' in div.style // false

False will be returned. This value is case-sensitive.

Case Sensitive

This means that, if the user passes boxShadow to the supports() function, it’ll fail. Let’s think ahead, and check if the first letter of the argument is lowercase. If it is, we’ll fix the error for them.

return function(prop) { if ( prop in div.style ) return true; prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); });};

Regular expressions to the rescue! Above, we’re checking if there is a single lowercase letter at the beginning of the string (^). Only on the condition that one is found, we use the toUpperCase() function to capitalize the letter.


We next need to filter through the vendors array, and test if there’s a match. For instance, if box-shadow is passed, we should test if the style attribute of the div contains any of the following:

MozBoxShadowWebkitBoxShadowMsBoxShadowOBoxShadowKhtmlBoxShadow

If a match is found, we can return true, because the browser does, indeed, provide support for box shadows!

return function(prop) { if ( prop in div.style ) return true; prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); }); while(len--) { if ( vendors[len] + prop in div.style ) { return true; } }};

Though we could use a for statement to filter through the array, there’s no real need to in this case.

The order isn’t important while statements are quicker to type, and require fewer characters There’s a tiny performance improvement

Don’t be confused by vendors[len] + prop; simply replace those names with their real-life values: MozBoxShadow.


But, what if none of those values match? In that case, the browser doesn’t seem to support the property, in which case we should return false.

while(len--) { if ( vendors[len] + prop in div.style ) { return true; }}return false;

That should do it for our function! Let’s test it out, by applying a className to the html element, if the browser supports, say, the text-stroke property (which only webkit does).

if ( supports('textStroke') ) { document.documentElement.className += ' textStroke';}

With a class name that we can now hook onto, let’s try it out in our stylesheet.

/* fallback */h1 { color: black;} /* text-stroke support */.textStroke h1 { color: white; -webkit-text-stroke: 2px black;}var supports = (function() { var div = document.createElement('div'), vendors = 'Khtml Ms O Moz Webkit'.split(' '), len = vendors.length; return function(prop) { if ( prop in div.style ) return true; prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); }); while(len--) { if ( vendors[len] + prop in div.style ) { // browser supports box-shadow. Do what you need. // Or use a bang (!) to test if the browser doesn't. return true; } } return false; };})();if ( supports('textShadow') ) { document.documentElement.className += ' textShadow';}

For a more comprehensive solution, refer to the Modernizr library.


View the original article here


Business plan to open a coffee shop, written by an experienced shop owner, worker and entrepreneur. Includes many bonuses and extras including email and personal consult.


Check it out!