Enhancing the User Experience [ 118 ] <ul> <! START results > <li><a href="products/view/{path}">{ name}</a></li> <! END results > </ul> Our search results page looks like this: Improving searches We could improve this search function by making it applicable for all types of content managed by the framework. Obviously if we were going to do this, it would need to be taken out of the products controller, perhaps either as a controller itself, or as a core registry function, or as part of the main content/pages controller. The results could either be entirely in a main list, with a note of their type of content, or tabbed, with each type of content being displayed in a different tab. The following diagrams represent these potential Search Results pages. This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 5 [ 119 ] And, of course, the tab-separated search results. Filtering products Another useful way to allow customers to better nd the products they are looking for is with ltering. Customers can lter down lists of products based on attributes, such as price ranges, manufacturer, weight, brands, and so on. Price range ltering should be simple enough. However, with attributes such as manufacturer or brands, we would need to extend the database and models representation of a product to maintain this additional information, and allow us to lter down based on these attributes. There are a few different ways in which we can store ltered results: In the user's session: This will be lost when the user closes their browser. In a cookie: This information will stay when the user closes their browser. In the URL: This would allow the customer to lter results and send the link of those results to a friend. In POST data: The information will only be stored for the one instance the lter is used. Let's try using the URL to store lter data. If we format lter data within the URL as filter/attribute-type/attribute-value-ID, then we can simply iterate through the bits of the URL, nd bits containing filter, and then take the next two parts of the URL to help build the lter. This way we can lter down products based on a number of attributes, for example filter/price/5/filter/weight/6. Of course, there is a limit to this, and that is the maximum length of a URL. • • • • This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Enhancing the User Experience [ 120 ] Product attributes Some attributes are already stored within the product, such as the weight and the price. However, we still need to store some ranges of these for our customers to lter by. As we discussed earlier, that we will store the attribute type as well as the attribute value within the URL, we can take the attribute type and either lter based on attribute values associated in the database (for example, products associated with brands for ltering by brand) or if the type is price or weight, we can detect that these should be ltered based on values stored in the products table. Database changes We are going to need to create three new database tables to effectively support product ltering as we have discussed. We will need: An attribute types table to manage types of attributes; for example, price, weight, brand, manufacturer, color, and so on An attribute values table to manage values and ranges of attributes; for example, < $5, $5 - $10, < 5 KG, Nike, Adidas, gold, red, and so on < $5, $5 - $10, < 5 KG, Nike, Adidas, gold, red, and so on An associations table to associate products with attribute valuesassociations table to associate products with attribute values table to associate products with attribute values Filter attribute types The attribute types table needs to be able to act as a grouping reference for attribute values, and also detect if an attribute value should be referenced against the products table, or the attribute associations table. Prices and weights would be referenced against the products table, where as brands, colors, and manufacturers would be referenced against the associations table. Field Type Description ID Integer (Primary Key, Auto Increment) A database reference for the attribute type. Reference Varchar Name Varchar The name of the type of attribute, for example price. ProductContainedAttribute Boolean Species if the attribute is part of a eld dened in the products table, such as price or weight, or not. • • • This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Download at Wow! eBook Chapter 5 [ 121 ] The following SQL represents this table: CREATE TABLE `product_filter_attribute_types` ( `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `reference` VARCHAR( 25 ) NOT NULL, `name` VARCHAR( 50 ) NOT NULL , `ProductContainedAttribute` BOOL NOT NULL ) ENGINE = INNODB COMMENT = 'Product Attributes for Filtering Product Lists'; Filter attribute values The attribute values table needs to store the name of the attribute and its relevant attribute type. Required elds are: Field Type Description ID Integer (Primary Key, Auto Increment) Name Varchar The name of the attribute, for example < $10 Attribute type Integer A reference to the type of attribute (for example size, price) Lower value Integer Used for attributes that are referenced within the products table (see below) Upper value Integer Used for attributes that are referenced within the products table (see below) Order Integer The order of the attribute in a list The upper and lower values are used when referencing against the products table, so we can get our framework to quickly construct queries using the lower and upper values as ranges for the WHERE clause of the query. The following SQL represents this table: CREATE TABLE `product_filter_attribute_values` ( `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR( 100 ) NOT NULL, `attributeType` INT NOT NULL, `order` INT NOT NULL, `lowerValue` INT NOT NULL, `upperValue` INT NOT NULL, INDEX ( `attributeType` ) ) ENGINE = INNODB COMMENT = 'Attribute values for filtering products' ALTER TABLE `product_filter_attribute_values` This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Enhancing the User Experience [ 122 ] ADD FOREIGN KEY ( `attributeType` ) REFERENCES `book4`.`product_filter_attribute_types` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE; Attribute associations The nal table we need is the one to associate various attributes with various products, the data we need to store is: The product ID The attribute ID The following SQL represents the previous table: CREATE TABLE `product_filter_attribute_associations` ( `attribute` INT NOT NULL, `product` INT NOT NULL, PRIMARY KEY ( `attribute` , `product` ) ) ENGINE = INNODB COMMENT = 'Product attribute associations for filtering product lists'; ALTER TABLE `product_filter_attribute_associations` ADD FOREIGN KEY ( `attribute` ) REFERENCES `book4` .`product_attribute_values` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `product_filter_attribute_associations` ADD FOREIGN KEY ( `product` ) REFERENCES `book4`.`content` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE; Filter options To display these attributes to our customers, and allow them to click on them to perform a lter, we need to build a list of attributes, build suitable URLs based on the attributes, and display them within the product list view. Displaying these attributes will involve some nested-looped template tags. The rst loop will be to generate headings and empty lists (with suitable template tags within) for the attribute types. Then we need to insert the loops of values into these. The simplest way to do this would be to do a query of all of the attribute types, cache it, and assign it to a template variable, and then do this for each set of values. Of course, that isn't a very good way, as we end up doing one query per set of attribute types, which isn't very efcient. We need to query the attribute types, query all attribute values and then process them into groups, and associate these groups with relevant template tags. • • This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 . manage values and ranges of attributes; for example, < $5, $5 - $10, < 5 KG, Nike, Adidas, gold, red, and so on < $5, $5 - $10, < 5 KG, Nike, Adidas, gold, red, and so on An associations. copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 5 [ 119 ] And, of course, the tab-separated search results. Filtering products Another. licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Download at Wow! eBook Chapter 5 [ 121 ] The following SQL represents this table: CREATE TABLE