Customers can filter down lists of products based on attributes, such as price ranges, manufacturer, weight, brands, and so on.. However, with attributes such as manufacturer or brands,
Trang 1<! 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.
Trang 2[ 119 ]
And, of course, the tab-separated search results
Filtering products
Another useful way to allow customers to better find the products they are looking
for is with filtering Customers can filter down lists of products based on attributes,
such as price ranges, manufacturer, weight, brands, and so on
Price range filtering 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 filter down based on these attributes
There are a few different ways in which we can store filtered 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 filter 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
filter is used
Let's try using the URL to store filter data If we format filter data within the URL as
filter/attribute-type/attribute-value-ID, then we can simply iterate through
the bits of the URL, find bits containing filter, and then take the next two parts of
the URL to help build the filter This way we can filter 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
•
•
•
•
Trang 3Product 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
filter 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 filter based
on attribute values associated in the database (for example, products associated with
brands for filtering by brand) or if the type is price or weight, we can detect that
these should be filtered 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 filtering 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
Key, Auto Increment)
A database reference for the attribute type
for example price
ProductContainedAttribute Boolean Specifies if the attribute is part of a
field defined in the products table, such as price or weight, or not
•
•
•
Trang 4[ 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 fields are:
Auto Increment)
example �� $10
attribute (for example size, price)
referenced within the products table (see below)
referenced within the products table (see below)
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`
Trang 5ADD FOREIGN KEY ( `attributeType` )
REFERENCES `book4`.`product_filter_attribute_types` (`ID`)
ON DELETE CASCADE ON UPDATE CASCADE;
Attribute associations
The final 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 filter, 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 first
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 efficient 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
•
•