Content¶
- Description
- The description of the shop. This is displayed within the front page of the shop.
- Static block
- The static block is displayed on top of the front page of the shop. See Static Block for more.
- Image
- The image of the shop.
LFS is an online shop based on widely-used software: Python, Django and jQuery. It is open source, free, easy to use, secure and fast.
For an up-to-date list of features please visit the official website: http://www.getlfs.com/features.
You should start with the concepts of LFS to get an overview what it can do and what not. After that you might go through the getting started tutorial. Once you have done this you could try to enter the data you like. When you stuck look into the how- tows for users or refer to the management interface reference.
Note
If you haven’t installed a shop yet you may use the demo shop to try things out. Please be aware that we reset it every two hours.
There are several places where you can find additional information and help:
Make sure you have installed:
The installation is straightforward and should last just a few minutes. Please execute following steps:
Note
If you encounter problems, please see trouble shooting.
Note
If you’re setting up a production environment then you should not use Django’s builtin development server (bin/django runserver). Instead, you’ll probably want to use uWsgi or Gunicorn servers. Check Django (and uWsgi/Gunicorn) documentation for details.
Note
For production environments you’re supposed to change robots.txt file (otherwise bots/crawlers like google bot will not be allowed to scan your site, which is not what you probably want). Default version of robots.txt is located at lfs_theme application: templates/lfs/shop/robots.txt. You should create your own ‘mytheme’ app with structure like: templates/lfs/shop/robots.txt and place it in settings.INSTALLED_APPS before(!) ‘lfs_theme’. Also note, that in production environment it is good to serve robots.txt directly from HTTP server like nginx or Apache.
Migration starting from 0.10 is based on Django’s default migrations, see: https://docs.djangoproject.com/en/1.8/topics/migrations/
Migrations from 0.5 - 0.8 to version 0.10 needs an intermediate step through version 0.9.
Migration from versions 0.5 - 0.8 to version 0.9 can be done with a migration command (lfs_migrate
)
which migrates existing databases up to version 0.9.
Move on to Getting Started.
Below is a description of changes that are useful to know about when upgrading LFS to newer version
This is not full reference of changes but at least some of them are described:
live
anymore. Updated manage/export/export.html, manage/export/export_inline.html,
manage/manufactuers/manufacturer.html and manage/manufacturers/manufacturer_inline.html to use data-url instead of just ‘data’
and use elem.data(‘something’) in JavaScriptThis document explains the first steps after the shop has been installed. For
the installation process please refer to Installation. If
you want to know more about single data fields within the forms below, you can
just click on the Help
menu, which opens the context aware help.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
Shop / Preferences
.Shop
tab.Name
. This is the name of the shop, for instance ACME Inc
which is used on several places, e.g. as part of the meta title of all HTML
pages.Shop Owner
. This is the full name of the shop owner.From E-mail Address
. This e-mail address is used as sender for all
e-mails which are sent from the shop, e.g. the order confirmation mail to the
shop customer.Notification E-Mail Addresses
. To this addresses all notification
messages will be sent. For example, if an order has been submitted.Save Shop
button.Default Values
tab.Price Calculator:
. This is the default for all
products, if the price calculator is not explicitly selected on a product.Invoice Countries
and Shipping Countries
. All selected
countries will be available to the shop customers for selection.Default Country
. This country will be preselected as default
country.Save Default Values
button.Shop / Product Taxes
and click on the Add Product Tax
button.Rate
(in percentage), for instance 19.0.Add Tax
button.Add Product Tax
site action
and executing steps 2 to 3.Shop / Delivery Times
and click on the Add Delivery Time
button.Min
, the minimal delivery time.Max
, the maximal delivery time.Unit
of this delivery time.Add Delivery Time
button.Add delivery time
link and
executing steps 2 to 3.Catalog / Categories
.Add Category
button.name
and a slug
.Add Category
button.Data
tab.Description
. This will be displayed within the detail view of
a category.Save Data
button.View
tab.Category Template
, In this case Category with Products
which means the assigned products of the category will be displayed.Save View
button.Catalog / Products
and click on the Add Product
button.name
and a slug
.Add Product
button.Data
tabSKU
of the product. This is the unique id of the product - taken
from your ERP for instance.Price
of the product.Short Description
. This will be displayed when the product is
displayed within a overview, e.g. when a category displays it’s assigned
products.Description
. This will be displayed within the detail view of
a product.Save Data
button.Categories
tabSave Categories
.Images
tabChoose Files
, browse to your images and select all images you want
to upload. You will see an upload indicator and all images will be uploaded.Data
tabActive
check box. Only active products are displayed to the
customers.Save Data
button.Goto Product
to visit the new product.Go to lfs_project/settings.py
and change LFS_LOCALE
to your needs (the
default one is en_US.utf8
). This will activate the correct currency and
number formats at the same time.
Usually there are several locale installed on your computer. In order to check which ones, please open a terminal and type:
locale -a
To install an english locale (on Debian/Ubuntu) please enter:
sudo apt-get install language-support-en
Note
After you have changed the locale you need to restart your instance to make it active.
This section describes the different product types of LFS.
Products are the most essential content object of LFS. They are goods which are sold to customers. LFS’ products manage a lot of data which are relevant for an online shop. Please see the product management interface reference to see all available data fields in detail.
LFS provides three types of products: default products, configurable products and products with variants. They are described in more detail in the following sections.
This is the simple and straightforward product of LFS. All other product types are based on the default product. It handles a lot of information like:
- General descriptions
- Prices and price units
- Images
- Attachments
- Accessories
- Related products
- Stock data
- SEO Data
- Portlets
- Properties
Each of this is described in more detail throughout this documentation.
A configurable product is a product with several properties and options from
which a customer can or needs to choose. For instance a property Color
and
its options red
, yellow
and green
. The selected options of the
properties can change the total price of the product, which is calculated by the
base price plus the prices of the selected options.
See also
A product with variants
is a product from which the customer can choose out
of an arbitrary amount of similar variants. It consists out of two parts: the
base and the variants.
The base can’t be sold to customers, but it serves as a container for the variants and provides default data, which can be inherited from the variants.
To create variants for a base global and local
properties are used, e.g. the property Color
and its
options red
, yellow
and green
. Each variant of a base belongs to a
unique combination of options of all properties of a base.
The variants can be sold to a customer. Each variant is a discrete product with its own data, e.g. own price, name and SKU. By default the variants inherit all data from the base. This data can be overwritten per variant and field.
See also
This section describes the concepts of categories.
Categories are used to structure the products of the shop.
Every category can have either one or no parent category. In this way the category tree is built, which serves as the essential navigation of the shop. If a category has no parent category, it is considered a top level category.
Every category can have an arbitrary amount of products and/or sub categories. What of these are displayed depends on the selected template. How these are displayed depends on several format information of a category.
Each category can have several assigned portlets. By default the portlets are inherited from the parent category or from the shop preferences (in case of top level categories). This can be blocked per slot.
In addition a static block can be assigned to a category, which is displayed on top of the category page.
Please see the description of the Category Management Interface in order to see more details of the information categories provide.
This section describes the concepts of manufacturers.
Manufacturers are bound directly to the products that are sold at the shop.
Every manufacturer can have zero or more products assigned. Each product can have zero or one manufacturer.
There is a page that lists all the manufacturers defined in the system. In order to use it at your shop you have to add new action pointing to /manufacturers url. From this page, users can dig deeper to see all the products from the specific manufacturer.
Please see the description of the Manufacturers Management Interface in order to see more details of the information manufacturers provide.
This section describes the concepts of criteria.
Criteria are a central concept of LFS and are used on several places in order
to restrict or display information on base of the current situation. For
example: which products are in the cart or in which country are these products
about to be delivered. Criteria have a value and an operator, which are the base
whether the criteria is true or false. This is described in more detail in the
section Criteria
below.
Criteria are used within:
For example a shipping method is only available when all of its criteria are true.
This paragraph describes the existing types of criteria and which operators they provide.
Tests the gross price of all products within the cart (without costs for shipping, payment and so on).
A number against the gross price of all products within the cart is tested.
Provides some tests for the payment methods of the shop.
Any selection out of all provided payment methods.
Provides some tests for the shipping methods of the shop.
Any selection out of all provided shipping methods.
Tests the country of the customer’s shipping address.
An arbitrary selection out of all existing countries.
Tests the total combined length and girth (clag) of all products within the cart. The clag is calculated as following:
(2 * maximum width) + (2 * total height) + maximal length
A number against the total combined length and girth of all products within the cart is tested.
Tests the total height of all products within the cart.
A number against the total height of all products within the cart is tested.
Tests the maximum length of all products within the cart.
A number against the maximum length of all products within the cart is tested.
Tests the total weight of all products within the cart.
A number against the total weight of all products within the cart is tested.
Tests the maximum width of all products within the cart.
A number against the maximum width of all products within the cart is tested.
This section describes the concepts of properties.
Generally, properties are used to extend products with miscellaneous data fields. Properties are attached to products with the help of property groups.
In particular properties are used to create products with variants, configurable products and filters or just to display generic information on a product. Additionally they can also be used to ask the shop customers to enter information for a product which is about to be ordered.
There are three types of properties, which are described in detail in the following sections.
The property’s value are plain text without any logic behind it.
The property value must be a float.
The step type is used for filtering. It can be chose from three different methods how the steps are created.
Validators are used to validate customer inputs into property fields.
Valid values which a shop customer could input into this field are: 1, 1.5, 2, 2.5 and 3.
The property is displayed as a select box.
Every single option for a Select Field Property
has to be entered. These
have following information:
The options are ordered by position, lower numbers are displayed first. The
names are displayed within several selection fields. if Add Price
is selected,
the price is used to calculate the total price of a Configurable Product.
This section describes the concept of local properties.
Local properties are added to single products. They are a convenient way to create single variants for a product with variants. In contrary to global properties they can not be used to create configurable products, create filters or to display several informations on a product.
This section describes how LFS calculates taxes.
Note
If you don’t have different taxes based on customers you can safely ignore the rest of this section.
There are two types of taxes: product taxes and customer taxes.
Product taxes
define the default tax for a product and are used to calculate
the default net or gross price of a product. Which one of these depends on the
type of price you have entered for your product. Product taxes are are assigned
directly on the product.
Customer taxes
define the tax for a specific customer respective for the
country in which the goods are to be delivered. These taxes are managed
centrally and selected automatically by LFS for the calculation.
Following we’ll explain how LFS calculates taxes.
Assuming that the entered price of a product is inclusive tax, i.e. the entered
price is the gross price of the product or in other words the selected Price
calculator
of the product is Price Includes Tax
.
LFS will calculate the net price of the product on base of the entered Product tax, the tax you have assigned to the product.
LFS will then calculate the product’s gross price for a customer on base of the customer tax which you have entered for the country of the customer’s shipping address. If there is no customer tax for the customer LFS falls back to the product tax in order to calculate the gross price.
Now let’s imagine you have entered the price of the product exclusive tax, i.e.
the net price of the product, or in other words the selected Price
calculator
of the product is Price Excludes tax
.
LFS will just take the entered price for the product and calculates the product’s gross price on base of the customer tax which you have entered for the country of the customer’s shipping address. If there is no customer tax for the customer LFS falls back to the product tax in order to calculate the gross price.
In both examples you see that the product tax is used when no customer tax is found. This means if you don’t have the need for different taxes based on customers you can safely ignore them at all and just assign your default taxes directly to the products.
This section describes the concept of static blocks.
A static block is a piece of information which are managed on a central place within LFS and can be reused from several content objects like the front page, categories or products. It consists out of an arbitrary HTML text and an arbitrary amount of attachments which can be provided for download.
An example is a description, image or video than should be displayed on several products or categories.
This section describes the concept of portlets in general and the default portlets in detail.
A Portlet is a piece of arbitrary information which can be assigned to every object, like shop, products, categories and pages. They are displayed in slots. A slot can have an arbitrary amount of Portlets. LFS ships with a left and a right slot and several default portlets. By default portlets are inherited from parent objects but it is also possible to block parent portlets per slot.
The inheritance path for categories and products is:
shop > category > sub category > product
The inheritance path for pages is:
shop > page root > page
This section describes all default portlets of LFS with their particular settings and properties.
This portlet displays the average rating of a product.
This portlet displays the category tree, which is the essential navigation for the shop.
2
the top level
categories are not displayed within the portlet. This can be useful if you
want to display them in the horizontal menu.0
only the current
category will be expanded. If this is 1
all top level categories are
expanded, etc.Note
top level categories have level 1, their sub categories have Level 2, etc.
This portlet displays the delivery time of a product.
This portlet displays products, which are selected within Marketing / Featured
This portlet displays a filter portlet for a category.
This portlet displays products which are for sale.
Display the products that were recently added to the shop
This portlet displays arbitrary HTML.
This portlet displays the top seller of the shop.
This section describes the concepts of actions.
Actions are used to place links on several locations within the shop. They belong to exactly one action group and the action group decides the location the actions are displayed within the shop. LFS ships with two action groups, the tabs, which constitutes the horizontal menu bar and the footer. Developers can easily add more action groups.
Actions enables the shop owner to link to arbitrary categories, products, information pages or even external web sites.
This section describes the concepts of delivery times.
The delivery times of single products and the cart is calculated automatically by LFS. Delivery times are managed centrally and are assigned to LFS’ shipping methods, that means they are generally dependent on the first valid or the selected shipping method of a customer, if this is not explicitly overwritten for a product (see below).
To get the delivery time for a single product (to display it within the product page), LFS calculates the first valid shipping method for the product and the customer (all criteria are true) and takes its assigned delivery time. It’s also possible to override this mechanism for single products with a manually delivery time.
To identify the delivery time for the total cart (to display it within the cart and the checkout page), LFS takes the shipping method the customer has currently selected and calculates on base of that the maximum delivery time of all products within the cart. The result can different from the selected shipping method as also in this case the manual delivery times of products are taken into account. Additionally the default delivery time is used if the selected shipping method for are product within the cart is not valid.
Additionally the internal delivery time (shop owner orders product) can be added to the delivery time for the customer.
This section describes the concept of shipping methods.
You can add as many shipping methods as you want.
All valid shipping methods are displayed for selection to the shop customer. A shipping method is valid if all criteria of the shipping method are true.
Shipping methods can have many prices which are, as the payment method itself,
also dependent on criteria. The first price which is valid - all of its criteria
are true - is the current price for the shipping method. If no price is valid
the default price is taken (from the Data
tab).
Shipping methods have also a delivery time which decides how long the delivery will take if a certain shipping method is selected by the customer.
This section describes the concept of payment methods.
You can add as many payment methods as you want.
All valid payment methods are displayed for selection to the shop customer. A payment method is valid if all criteria of the payment method are true.
Payment methods can have many prices which are, as the payment method itself,
also dependent of criteria. The first price which is valid - all of its criteria
are true - is the current price for the payment method. If no price is valid the
default price is taken (from the Data
tab).
This section describes the marketing features of LFS.
Accessories are products which are supposed to be sold together with a product, like shingles to a summerhouse. They are not bidirectional but they need to be entered on each product itself.
Accessories are displayed within the product view
and could be added to the
cart alongside with the product. They are also displayed within the added to
cart view
(the view is displayed after a shop customer has added a product to
the cart) in order to offer them to be also added to the cart.
Discounts are a possibility to give a price reduction to customers. They can be absolute or percentaged based on the total cart price. Discounts can be restricted by criteria and they are only given if it meets all criteria. The shop owner can add an arbitrary amount of discounts.
Featured products are several product which are supposed to be exposed to the customer for any reason. They are management manually an can be displayed displayed to the customer via the featured product portlet.
Shop owners can send rating mails to shop customers in order to ask them to rate the products they bought. See also review concepts for more information.
Top seller are best sold products of the shop. They are calculated automatically but can be also manipulated manually. They are displayed within the top seller portlet
Vouchers are another possibility to give a price reduction for customers. The price reduction can be absolute or percentaged based on the total cart price.
They are generic character strings which can be distributed to customers. If a valid voucher string is entered within the cart or as part of the checkout process the customer gets the price reduction.
Vouchers can be limited by a start and an end date or a minimum cart price.
Vouchers expire when they have been used for a certain amount of times. A common way is to expire the voucher right after it has been used the first time.
The shop owner can add an arbitrary amount of vouchers. They can be of the same or of different types.
This section describes the reviews of LFS.
Shop customers can review the products.
A review consists of a score of 1-5 stars and an arbitrary text. The average rating for a product is calculated automatically and displayed within the product view and the average rating portlet.
Logged in customers can review a product only once, anonymous customers just once in a session.
Shop administrators can influence the way reviews are handled, e.g. whether reviews are moderated or which fields are required. See settings for more.
Shop owners can send rating mails to shop customers in order to ask them to rate the products thy bought.
This section describes the pages of LFS.
A page is a simple piece of HTML within the shop. It can be used to create landing pages or to display other information to shop customers like terms and conditions.
Pages are automatically displayed within the pages portlet or can be referred by actions.
Like other objects pages can have portlets.
This section describes the concepts of images.
LFS provides two kinds of images: product images and global images.
Product images managed within the images tab of a product and are attached to a single product. They are displayed automatically within the detail view of the product and the first image also within the category overview view.
Global images are managed on a central place and can be easily embedded within any WYSIWYG text field within LFS (e.g. within a page).
To do that one just have to click on the image icon of the WYSIWYG
editor (see below), select the image in question, adapt the class and size of
the image and click on the insert image
button.
This section describes the management interfaces of the Shop
menu.
This section describes the management interface for actions.
Tabs
to display the action
on the horizontal menu or Footer
to display the action on the footer
of the shop.This section describes the management interface for delivery times.
This section describes the management interface for manufacturers.
Amount of columns and rows which are used to display the products of the manufacturer. The amount of products which are displayed calculates by cols * rows. If there are more products than that the products are automatically paginated.
Note
This is only available if Active Formats
is True.
This tab is used to optimize your pages for search engines. You can enter data for all meta data fields. However LFS provides some reasonable default values for all fields.
Note
You can use several placeholders within these fields:
In order to assign products to the manufacturer, select the check boxes of the
corresponding products within the section Selectable Products
and click on
Add To Manufacturer
.
Within this tab you can assign categories and products to the manufacturer.
To assign all products of a category to the manufacturer just check it. If you want just a sub category or single products of it, click on the category to expand the children.
This section describes the management interface of payment methods.
Note
Default payment methods can’t be deleted.
The type of the payment method. Dependent on that additional fields for input (within the checkout process) will be displayed. There are three types:
Here you can add criteria for the payment method. The payment method is only available for shop customers if all criteria are true.
Please see How to manage payment methods to see how to add criteria.
Here you can add additional prices for the payment method based on criteria.
If prices are given the first price which meets all criteria is taken for the
payment method. If no prices are given, the default price of the Data
tab
is taken.
Please see How to manage payment methods to see how to add prices.
This section describes the preferences management interface.
There are three checkout types:
This field stores the format of the order number. The integer part which is
stored in Last order number
can be formatted with Python’s string
formatting operators,
e.g.:
DOE-%04d-2012 will return DOE-0001-2012
Whereas %04d
represents the integer part of the order number, which is
stored in Last order number
.
This tab is used to optimize the start page for search engines. One can enter data for all usual HTML meta data fields.
meta title
tag of the start page. By
default the Name
field of the Shop
tab is used (see above).meta keywords
tag of the start page.meta description
tag of the start page.Note
Following placeholder can be used within these fields:
This tab is used to assign Portlets to the shop.
Add portlet
.This section describes the management interface of shipping methods.
Here you can add criteria for the shipping method. The shipping method is only available for shop customers if all criteria are true.
Please see How to manage shipping methods to see how to add criteria.
Here you can add additional prices for the shipping method based on criteria.
If prices are given the first price which meets all criteria is taken for the
shipping method. If no prices are given, the default price of the Data
tab
is taken.
Please see How to manage shipping methods to see how to add prices.
This section describes the management interface for product taxes.
This section describes the management interface for customer taxes.
Note
You can add just one tax rate per country.
This section describes the management interface for global images.
Select images
button and select as many images as you want
within your browsers pop-up window. You can use shift click to select a
range of images at once and ctrl (cmd for apple users) click to select
more images. Now click on open to start the upload process. You will now
see a progress bar meanwhile your images are being uploaded.Delete
button. Alternative you can click on the Toggle
selection
button in order to inverse the current selection.This section describes the management interfaces of the Catalog
menu.
This section describes the category management interface.
In order to move categories, hold it on the handle left beside the category name and drag and drop it to the new place.
Show all products
If this check box is activated also the products of the sub categories are displayed. Otherwise only the direct products are displayed.
Note
This is only available when a the products of the category are displayed. (see Category Template).
Amount of columns which are used to display the sub categories. Always all direct categories of the category are displayed.
Note
This is only available if active formats is True and a category template is selected.
Amount of columns and rows which are used to display the products of the category. The amount of products which are displayed calculates by cols * rows. If there are more products than that the products are automatically paginated.
Note
This is only available if Active Formats
is True and a product
template is selected.
This tab is used to assign and remove products to the category.
In order to assign products to the category, select the check boxes of the
corresponding products within the section Selectable Products
and click on
Add To Category
.
In order to remove products from the category, select the check boxes beside the
corresponding products within the section Selected Products
and click on
Remove From Category
.
In order to make it easier to find products you can filter them by name, SKU and category. For that enter on top of the according section the name or the SKU into the text box and select the category out of the select box.
This tab is used to optimize your pages for search engines. You can enter data for all meta data fields. However LFS provides some reasonable default values for all fields.
Note
You can use several placeholders within these fields:
This tab is used to assign portlets to the category.
Save blocked parent
slots
button.Add portlet
.This section describes the product management interface.
Price Calculation
Warning
This is experimental feature. Use it with care and take notice that these could be replaced with something different in future.
Note
This is only available for
Configurable Products
.If the check box is checked the input field could contain a formula to calculate the price of a
Configurable Product
. In this case one can refer to the values of a property in order to calculate the price.Generally the formula could contain any valid Python expression which is able to be evaluated with
eval
with two additionally tokens.If an error, occurs the default price of the product is taken.
Available tokens:
product(<attribute>) Refers to the attribute of the current product property(<id>) Refers to the value of the property with the given <id>Example 1:
property(15) * product(price)Which means: take the entered value of the property with the id 15 and multiply it with the product’s price.
Example 2:
product(price) * property(54) * property(55) + property(56)Which means: multiply the product’s price with the values of the properties with ids 54, 55 and add the value of the property with the id 56.
Determines how the product price is calculated using the product price and tax stored in the database. If you leave this field blank, your pricing calculator will default to the shop price calculator.
LFS ships with two pricing calculator methods: Price Includes Tax
, which
means the product price in the database includes tax and Price Excludes
Tax
, which means the product price in the database excludes tax.
If the check box is activated the entered for sale price is active. On all views the standard price is displayed stroked and the for sale price is displayed emphasized.
For variants following is true:
for sale
state of the base article.Integer
, which means the
quantity must be an integer and all decimal places are ignored. Decimal
0.1
, which means the quantity must be a decimal number with one place and
more decimal places are ignored. Decimal 0.01
, which means the quantity
must be a decimal number with two places and more decimal places are ignored.If this is activated the base price of the product is displayed within product detail view and category products view.
For variants following is true:
base
price unit
and base price amount
are taken from the base article.base price unit
and base price
amount
are taken from the variant.The amount, which is used to calculate the base price of the product. The base price of the product is:
base price = price / base price amount
Within this tab you can assign categories to the product. To do that just
select all categories the product should be a part of and click on Save
Categories
.
Note
You can also assign products to categories.
Within this tab you can add images to the product.
Images are displayed on the details view of the product. The first image is the default image of the product and is also displayed on overviews like the category detail view or search results view.
Select images
button and select as many images as you want
within your browsers pop-up window. You can use shift click to select a
range of images at once and ctrl (cmd for apple users) click to select
more images. Now click on open to start the upload process. You will now
see a progress bar meanwhile your images are being uploaded.Update
button.Delete
button.Within this tab you can add attachments to the product. They are displayed for download on the detail view of the product.
Select files
button and select as many attachments as you
want within your browsers pop-up window. You can use shift click to select
a range of images at once and ctrl (cmd for apple users) click to select
more images. Click on select to start the upload process. You will now
see a progress indicator meanwhile your images are being uploaded.Update
button.Delete
button.Within this tab you can manage the variants of a Product with Variants
.
Note
This is only displayed for Products with Variants
.
Select all property groups which are supposed to be used to create variants.
After you have selected the property groups you want, you will notice that the
properties of the groups are provided to create variants within the Variants
section below.
Note
Only properties with select fields will be taken into account.
Local Properties
can be used to create variants without using Property
Groups
. To add properties click on the stencil and add properties and property
options. After you add local properties you will note that these are provided to
create variants within the Variants
section below.
Note
Local properties can not be used for filtering.
Within this section single variants of the Product with Variants
are
managed.
To add variants to the Product with Variants
, select the options
combination you want to add and click on the Add Variant(s)
button. If
you select all
all combinations of this property and its options will be
created automatically.
You can pre-fill several fields of the new variants. All fields can be changed later.
There are several fields of the variants which you can edit directly on this section. All others can be edit on the variant detail view.
To save changed variants click on the Save
button.
Delete
button.The category variant determines which variant is displayed within the category products view.
The display type determines how variants are displayed within the product detail view
All properties are displayed as select boxes with the property options as options.
Note
If the customer selects a combination, which doesn’t exist he will get a message which says so.
Within this tab you can manage the accessories of a product.
Within the Selectable Products
section select all check box beside the
product you want to add as accessory to the product and click on Add To
Accessories
.
Note
You can filter the selectable products by name and category with the input
fields on top of the Selectable Products
section.
Within the Selected Products
section change the values you want and click
on Save accessories
.
Within the Selected Products
section select all check boxes beside the
products you want to remove from the product and click on Remove From
Accessories
.
Within this tab you can manage all stock related information of the product, like the dimension, stock amount and delivery dates.
The values of the product which are considered shipping relevant, i.e. the product within its package.
Stock amount
(see below).Note
If Order time
and Order at
is given the total delivery time
is
calculated based on this two fields and the default Delivery time
.
If this is checked the product can only be sold in packings.
For variants following is true:
packing
amount
and packing unit
are taken from the base article.packing amount
and packing unit
are taken from the variant.This tab is used to optimize the product for search engines. One can enter data for all usual HTML meta data fields. However LFS provides some reasonable default values for all fields.
meta title
tag of the product’s detail
view. By default the name of the product is used.meta keywords
tag of the product’s detail
view. By default the short description of the product is used.meta description
tag of the product’s
detail view. By default the short description of the product is used.Note
Following placeholders can be used within these fields:
This tab is used to assign portlets to the product.
Save blocked parent
slots
button.Add portlet
.This tab is used to assign properties to the product (via property groups) and add values to them.
To do that select the Property groups
you want to assign to the product and
click on Update property groups
. Then enter the values for the properties
you want and click on Update properties
.
Dependent on the kind of the property you can add values for the default value, the filter value and the displayed value.
This section describes the products overview management interface.
Here you can bulk edit products.
In order to delete products activate the check box on the left side of the
products in question and click the Delete
button. In order to modify
products make the changes in the product fields and click the Save
button.
Warning
Deletions or modifications can’t be made undone.
In order to display just a sub set of products you want to change you can use
the filter section on top of the screen. A product must join all filters in
order to be displayed, in other words the filter fields are joined by a logical
AND. To set the filters click on the Submit
button. To reset the filters
click on the red button on the most right site of the filter section.
This section describes the management interfaces of the Properties
menu.
This section describes the management interface for property groups
.
Deletes the current displayed property group.
Warning
Please note that all values which have been assigned to products and properties of this property group will get lost.
Within this tab you can manage properties for this property group.
Properties
section on the left side and click
on Add to Property Group
.Update properties
.To remove properties from the group select the check boxes beside the properties
you want to remove within the Selected properties
section on the right
side and click on Remove from Property Group
.
Warning
Please note that all values which have been assigned to products of this group and the removed property will get lost.
Within this tab you can assign products to the property group. All products will have the properties of this property group.
Note
The selectable products can be filtered with the text field (name) and select box (categories).
Products
section on the left side and click
on Add to Property Group
.To remove products from the group select the check boxes beside the products
you want to remove within the Selected products
section on the right
side and click on Remove from Property Group
.
Warning
Please note that all values which have been assigned to properties of this group and this product will get lost.
In this tab you can assign values for every product / property pair within this group.
For that just enter the you want and click save values.
Note
You can also enter the values within the Properties
tab of the product.
See here for more.
This section describes the management interface for properties.
Deletes the current displayed property.
Warning
Please note that all values which have been assigned to products for this property will get lost.
Configurable
is checked.This section describes the management interfaces of the HTML
menu.
This section describes the management interfaces of pages.
In order to sort pages, take the handle on besides a page within the navigation on the left side and drag and drop it to the position you want the page to be.
This is the root of all pages. You can add portlets to it which are inherited from all other pages.
This tab is used to optimize your pages for search engines. You can enter data for all usual HTML meta data fields. However LFS provides some reasonable default values for all fields.
Note
You can use several placeholders within these fields:
This tab is used to assign portlets to the page.
Save blocked parent
slots
button.Add portlet
.This section describes the management interface of Static Blocks
.
Within this tab you can add arbitrary files to the Static Block. These
are provided for download if Display Files
is checked (see above).
Select files
button and select as many files as you want
within your browsers pop-up window. You can use shift click to select a
range of files at once and ctrl (cmd for apple users) click to select
more files. Now click on open to start the upload process. You will now
see a progress bar meanwhile your files are being uploaded.Update
button.Update
button.Delete
button.This section describes the management interfaces of the Customers
menu.
Within the customers overview all customers are displayed.
To sort the displayed customers click on the columns title.
To view a customer in detail just click on the row of the customer.
Within the customer detail view you can see several information about a single customer: the id and the registration status, the current invoice address and shipping address, the current cart of the customer, if there is one. Click on the cart row to see it in detail. You can also check which orders the customer has submitted and the state of the them. Click on the order row to see it in detail.
With the page navigation you can navigate through all customers. To filter the
displayed customers by name just fill in the name field and click Submit
. To
reset the filter just click on the red X
button.
Within the orders overview all orders are displayed.
Note
Sorting is not available at the moment.
Within the order detail view you can see several information about a single order:
You can filter and navigate through the displayed orders on the left:
Submit
. For convenience you can click on links beside the start field.
T = today, Y = yesterday, W = week.Submit
.Submit
.X
button.Delete order
button and
answer the confirmation question with Yes
.Resend
button and answer the confirmation question with
Yes
.Change
button.Within the carts overview all carts are displayed.
Note
Sorting is not available at the moment.
Within the cart detail view you can see several information about a single cart:
You can filter and navigate through the displayed carts on the left:
Submit
. For convenience you can click on links beside the start field.
T = today, Y = yesterday, W = week.X
button.Within the reviews overview all existing reviews are displayed.
Within the review detail view you can see several information about a single review:
You can filter and navigate through the displayed reviews on the left:
Submit
.Submit
.X
button.Delete review
button
and answer the confirmation question with Yes
.To change the activity state of the current review select the desired
state and click on the Change
button.
Note
Only active reviews are displayed.
This section describes the management interfaces of the Marketing
menu.
This section describes the featured products management interface.
To add featured products check the check boxes beside the products you want to add
(within the Products
section) and click on Add to featured products
.
To update featured products change the entries in question and click on the
Save featured
button (see image below).
To remove featured products check the check boxes beside the products you want
to remove (within the Featured products
section) and click on Remove from
featured
.
To add top sellers check the check boxes beside the products you want to add
(within the Products
section) and click on Add to topseller
.
To update top sellers change the entries in question and click on the Save
topseller
button (see image below).
To remove top sellers check the check boxes beside the products you want to
remove (within the Topseller
section) and click on Remove from
topseller
.
This section describes the management interface for discounts.
Determine if discount can be summed up with other discounts/voucher. To calculate final discount on order:
- value of discounts/voucher able to sum up is calculated
- value of highest discount/voucher that cannot be summed up is calculated
- higher of two above values is used
Within this tab you can assign criteria to the discount. The discount is only given if a customer meets all criteria.
This section describes the management interface for vouchers.
Within the data tab you can change the name of the voucher group.
Within the vouchers tab you can manage the vouchers of the current voucher group.
Determine if Voucher can be summed up with discounts. To calculate final discount on order:
- value of discounts/voucher able to sum up is calculated
- value of highest discount/voucher that cannot be summed up is calculated
- higher of two above values is used
In order to add vouchers, fill in the provided form and click on Add
Vouchers
.
To delete vouchers check all voucher you want to delete and click on Delete
Vouchers
.
Within the options tab you can change the options for voucher numbers.
Note
The current options are only effective for upcoming vouchers.
Here you can send your customers invitations to rate their bought products.
All customers with an order that is closed
for at least 14 days will get a
mail with links to a rating form to all bought products of this order.
You can safely send the mails more than once, LFS will store all orders which have already got an e-mail and don’t send the mail again.
In order to do that, just click on the Send Rating Mails
button.
This section describes the management interfaces of the Utils
menu.
Here are some miscellaneous utilities for LFS. Actually you should never have to use theme.
LFS provides an aggressive caching strategy for all content like categories and products (dependent on your environment). Actually LFS deletes out dating content automatically. However if you experience old content you can always empty the cache manually.
LFS manages internal category levels. Here you can create them safely new if something went wrong. However, you should never have to use this.
Within this tab you can export selections of products.
Generic
script. Developers can add more scripts.Within this tab you can select which products are supposed to be exported.
To export whole categories just select the check box beside the category you want to export. If you want just a sub category or single products of category, click on the category to expand the children.
For every category you can overwrite the default settings which variant(s) of a
product with variants
will be exported. This is either the default variant,
the cheapest variant or all variants.
In this how-to you will learn how to add a product with variants.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
Go to the LFS Management Interface.
Go to Catalog / Products
.
Click on Add Product
in order to add new product.
Enter the Name
, and the Slug
of the product and click on Add
product
.
Now you can enter further data as you would do for standard products for
instance the price. Please note that this are in case of a Product with
Variants
just default values, which can be overwritten for every single
variant later.
Change the product’s type from Standard
to Product with Variants
and click change
. You will notice that there is now a Variants
tab.
Go to the Variants
tab.
Click on the pencil left beside the Local Properties
title in order to
display the local properties add form.
Enter Color
in the text field and click on Add Property
.
Note
You can also use global properties to create variants, but this is beyond of these how-to.
Enter Red
into the now provided option field and click on Add Option
.
Repeat step 10 with Green
and Blue
.
Note
For convenience you can also add Red, Green, Blue
to add all options
at once.
Now go to the Variants
section and select All
below Color
option. Click on Add Variants(s)
. This will create all variants based
on the option you have entered above.
Click on the pencil of a variant in order to open its edit form.
By default the data is inherited from the parent. In order to override a field activate it - check the check box beside the field - and enter some information to it for instance for the price of a variant.
Repeat that for every variant you want to change.
Click on the Base Article
site action in order to go back to the parent
product.
Go to the Variants
tab. You should be there automatically.
Check the Active
check box. This will check the active check boxes of
all variants and click on the Save
button.
Select the default variant by checking one of the radio boxes below the
Default
title. This variant is displayed if the shop customer visits the
Product with Variant
.
Go to the Product
tab.
Check the Active
check box. This will activate the whole Product with
Variants
.
Now click on Goto Product
and you will see your newly created Product with
variants
. There is a Variants
section from which the customer can select
the variants the product provides. All information of the product (which has been
overwritten by a variant) are automatically updated if the customer choose a
variant.
In this how-to you will learn how to add a configurable product.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
A configurable product is based on properties. So we need to enter them at first.
Properties / Properties
menu.Add Property
site action and enter the name of the property,
for instance “Hard drive”. Then click on the Add Property
button.Configurable
within the data form of the property and click on
Save Property
.Field Type
to Select Field
and click on Save Property
Type
.
- Name: 250GB / Price: 50.0
- Name: 500GB / Price: 100.0
- Name: 750GB / Price: 150.0
Add Property Group
site action and enter the name of the
property group, for instance “PC”. Then click the Add Property Group
button.Properties
tab, select the properties “Hard drive” and “RAM”
and click on Assign Properties
.Catalog / Products
menu.Add product
in order to add new product.Add product
.Standard
to Configurable
and click
Change
.Properties
tab.PC
property group and click on Update Property Group
.Update Default
Values
. The default values will be selected when a customer views the
product.Now click on Goto Product
and you will see that the product has a select box
from which the customer can select the options you provide above. The prices are
automatically updated when the options are changed. If the customer adds the
product to the cart, the selected option is stored on the product.
Add Properties
section above).In this how-to you will learn how to create a product with filters. At the end of it you will have added a property group a property, a category with three products and a filter portlet.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
First we will add the corresponding filter portlet:
Filter
portlet and click Add portlet
. Enter Filter in the
Title
field and click Save portlet
. You should now see the filter
portlet within the Left slot
section.Now we will add properties, which are the base for the product filters.
Add property
. (If there is no property.
at all yet you will see the Add property form automatically).Name
of the property, in our case Size and click
Add property
.Field type
, select Select field
and click Save property
type
.Options
and fill in the Name
field. In our case Small.
Click Add option
.Now we will add a property group.
Note
Every property has to belong exactly to one property group in order to use it with a product.
Add property group
button.
(If there is no property group at all yet you will see the Add property
group form automatically).Name
of the property, in our case T-Shirts and click
Add property group
.Now assign the property to the property group:
Assign properties
.You should now see Size within Assigned properties
.
We will now add the Property group
to some products.
Add product
. (If there is no product at all
yet you will see the Add product” form automatically).Name
T-Shirt One and Price
10.00 and click Add product
.No we assign values to the properties:
Properties
tab of that product.Property group
T-Shirts and click Update property groups
You will now see the Property
Size.Size
Small.We need to make the products active:
Active
for all products and click Save
.Now we add a new category T-Shirts:
Note
Filtering takes place on products of a category, hence we add a category for our newly products.
Name
: T-Shirts and click Add category
.Now we assign the products to the category:
Add to category
.Now we are ready to preview our new content:
Preview
button. You should now see the filter portlet
with the ability to select the sizes Small, Middle and Large and prices 0 - 500.00 and 501.00 - 1000.00.Field type
or the
Unit
field.In this how-to you will learn how to add and edit payment methods and how to add criteria and prices for them.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
In order to add/edit a payment method please go to Management / Shop / Payment Methods.
If there are no payment methods yet, you will automatically get to the add
payment method form. Otherwise the first payment method is displayed and
you can click on a payment method to edit this or on Add payment method
to add a new one.
If you have done that you can edit or enter the data for a payment method as described below.
The data tab contains all core data for the payment method.
Now fill in the fields:
Name: The name of the payment method, which is displayed to the shop customer.
Description: A short description of the payment method, which is also displayed to the customer.
Note: A note of the payment method, which is displayed on the confirmation mail after the shop customer has been checked out.
Priority: The first valid payment method with the highest priority (smaller number) method is displayed to the customer.
Image: An image for the payment method, which is displayed to the shop customer.
Tax: The included tax of the payment method’s price.
Price: The default price of the payment method. This can be overwritten within the price tab (see below).
Module: The dotted name of the external package which processes the payment (this is for developers only).
Type: The type of the payment method. Dependent on that additional fields for input (within the checkout process) will be displayed. There are three types at the moment:
- Plain No additional fields are displayed.
- Bank Fields for a bank account are displayed.
- Credit Card Fields for a credit card are displayed.
And click on the Save
-button.
Optional you can add some criteria to the payment method. Only when all criteria are true the payment method is displayed to the shop customer.
To add criterion proceed as following:
Add criteria
-button (adds a criterion on first position) or on the
plus
button beside a criterion (adds a criterion below)Weight
(this is the weight of all cart items).Less than equal to
.Save criteria
.To update criteria proceed as following:
Save criteria
To delete a criterion proceed as following:
minus
button beside the criterion.Save criteria
.Optional you can add additional prices to the payment method and restrict them with criteria. The first price which meets all criteria will be taken.
To add a price proceed as following:
Prices
tab.Add price
.Edit criteria
link. A pop-up
window will open.Add criteria
and change the criteria type, the operator and
the value to your needs.To update/delete a price proceed as following:
Update prices
.Delete prices
.In this how-to you will learn how to add and edit shipping methods and how to add criteria and prices for them.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
In order to add/edit a shipping method please go to Management / Shop / Shipping Methods.
If there are no shipping methods yet, you will automatically get to the add
shipping method form. Otherwise the first shipping method is displayed and
you can click on a shipping method to edit this or on Add shipping method
to add a new one.
If you have done that you can edit or enter the data for a shipping method as described below.
The data tab contains all core data for the shipping method.
Now fill in the fields:
- Name: The name of the shipping method, which is displayed to the shop customer.
- Description: A short description of the shipping method, which is also displayed to the customer.
- Note: A note of the shipping method, which is displayed on the confirmation mail after the shop customer has been checked out.
- Priority: The first valid shipping method with the highest priority (smaller number) method is displayed to the customer.
- Image: An image for the shipping method, which is displayed to the shop customer.
- Tax: The included tax of the shipping method’s price.
- Price: The default price of the shipping method. This can be overwritten within the price tab (see below).
Click on Save
-button
Optional you can add some criteria to the shipping method. Only when all criteria are true the shipping method is displayed to the shop customer.
To add criterion proceed as following:
Add criteria
-button (adds a criterion on first position) or on the
plus
button beside a criterion (adds a criterion below)Weight
(this is the weight of all cart items).Less than equal to
.Save criteria
.To update criteria proceed as following:
Save criteria
To delete a criterion proceed as following:
minus
button beside the criterion.Save criteria
.Optional you can add additional prices to the shipping method and restrict them with criteria. The first price which meets all criteria will be taken.
To add a price proceed as following:
Prices
tab.Add price
.Edit criteria
link. A pop-up
window will open.Add criteria
and change the criteria type, the operator and
the value to your needs.To update/delete a price proceed as following:
Update prices
.Delete prices
.In this how-to you will learn how to setup paypal for your shop
- Click on “Profile” - “Instant Payment Notification Preferences”
- Set the Notification URL to http://www.yourdomainname.com/paypal/ipn/
- Turn IPN On
- Click on “Profile” - “Website Payment Preferences”
- Turn on “Auto Return”
- Set the “Return URL” to http://www.yourdomainname.com/paypal/pdt/
- Set “Payment Data Transfer” to On, this will create an Identity Token for us.
Copy our seller information to settings.py e.g.:
PAYPAL_RECEIVER_EMAIL = "seller_1262786866_biz@yourdomainname.com"
PAYPAL_IDENTITY_TOKEN = "j0Iw3M4l6znE45kWkyQs43PkwC9bkaceteiWXfddg5q_CW1Ev4HGuqVPPfBG"
Deploy your site to a live internet site for testing (Paypal servers must be able to see your site).
When you are finished testing your site and ready to go live, set up a live Paypal Business account (Website Payments Standard account has been reported to work) and repeat steps 5-8
LFS provides a generic export engine for products (see here for more). In this tutorial you will learn how to create your own scripts to format the data like you want to.
Note
If you don’t have a working LFS instance yet, you can just use our demo shop at http://demo.getlfs.com. Please be aware that we reset the database every two hours.
In order to create a new export script you should first create a new Django application (or use an existing one). This is beyond this tutorial. If you do not know how to do this, please refer to the excellent Django tutorial.
Within the __init__.py of your application create a function that will return the products, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # python imports
import csv
# django imports
from django.http import HttpResponse
from django.core.mail import send_mail
# lfs imports
from lfs.export.utils import register
def export(request, export):
"""Export method for acme.com
"""
response = HttpResponse(mimetype="text/csv")
response["Content-Disposition"] = "attachment; filename=acme.txt"
writer = csv.writer(response, delimiter=";", quotechar='"', quoting=csv.QUOTE_ALL)
for product in export.get_products():
writer.writerow(product.id, product.get_name())
return response
register(export, "acme.com")
|
The code explained
get_products
method of the
passed export object.Now you can go the management interface, create a new export, select the
products and your newly script and call it via the Export
button.
You might want to create a cron job which calls your script regularly. (See here for more)
Celery
is a distributed task queue that can be used to send e-mails from LFS asynchronously.
There is no special integration in LFS for Celery
but there are general patterns for Django based projects
that can be used to get asynchronous e-mail backend.
You need:
as well as some Celery backend, eg Redis. Consult Celery documentation for details.
Follow the Celery’s first steps with Django and django-celery-email documentation.
This section describes how to develop LFS.
Warning
This is only for development. Don’t use this version in production. We might break the head, add stuff which need database migrations or introduce some security issues, etc.
There is an installer based on zc.buildout, which should make the installation straightforward:
Note
You might want to fork LFS on GitHub and point to it within buildout.cfg first.
If you consider to contribute code to LFS, please read the following statements first:
First of all, you are very welcome!
Generally, it would be great if you would discuss new stuff first. We are very reluctant to add new things. Every new feature should have a real live use case. Find us on IRC or the LFS Google Group.
Fork LFS GitHub and send us pull requests.
Please make sure that you just add related code to your fork. This makes it easier to review and pull your code.
The code must be put under a permissive free software licenses like BSD, otherwise we can’t add it. For instance, code under the GPL or a other copyleft software licenses won’t be added to the core.
Python code must follow PEP 8. The maximum of 79 characters per line is the only exception. You may want to check your code with pep8. The following statement should run without complaints:
$ pep8 --repeat --ignore=E501 /path/to/lfs
Every new feature must have unit tests and documentation.
All tests must pass. Please check this with:
$ bin/django test lfs.core
New features shouldn’t make LFS slower. Please see Benchmarking LFS.
Add yourself to CREDITS.txt.
Please refer to Contributing translations.
This section describes how to test LFS.
Testing is based on nose and django-nose.
Test everything:
$ bin/django test lfs.core
Test everything with coverage (you’ll find the coverage report in the current directory):
$ bin/django test lfs.core --with-coverage --cover-package=lfs --cover-html
Test only the catalog:
$ bin/django test lfs.catalog
Test only the catalog with coverage (you’ll find the coverage report in the current directory):
$ bin/django test lfs.catalog --with-coverage --cover-package=lfs.catalog --cover-html
Test only one method without capturing the output (this is helpful if you want to debug a test with pdb):
$ bin/django test lfs.catalog.tests:ViewsTestCase.test_file -s
This section describes how to benchmark LFS.
The development buildout comes with lfs_bench
, a small application, which
provides some tools to benchmark LFS.
You can use it in case you want to optimize LFS in terms of speed. In case you want to development a new feature, please compare the versions with and without this feature and try to not slow down LFS.
Install JMeter
Prepare the database:
$ bin/django lfs_init
$ bin/django lfs_generate_content_for_benchmark
Start LFS
- Start LFS in production mode, for instance with
bin/django-gunicorn
. and a reverse proxy in front of it. In other words don’t use the development server.- Set DEBUG to False
Make sure you start it from the buildout base directory (that’s the same directory you start Django from):
$ /path/to/jmeter/bin/jmeter -t src/lfs_bench/lfs_bench/jmeter/lfs.jmx -p src/lfs_bench/lfs_bench/jmeter/user.properties
Summary Report
for
instance.Prepare the database:
$ bin/django lfs_init
$ bin/django lfs_generate_content_for_benchmark
Start LFS
- Start LFS in production mode, for instance with
bin/django-gunicorn
. and a reverse proxy in front of it. In other words don’t use the development server.- Set DEBUG to False
Use ab
, for instance like that:
$ ab -n 1000 -c 20 http://localhost/product-1-1-1
Check the results.
The development buildout provides a middleware by default, which let you profile
single requests. Just suffix the request with ?prof
in order to get
profiling data, for instance:
http://localhost/product-1-1-1?prof
See also:
This section describes how to modify and create new models in LFS
Since version 0.8 LFS uses South migrations so you’re encouraged to read South documentation first. If you need to modify models layer of LFS then you should use ‘shemamigration’ command. If you have to migrate data then you should use ‘datamigration’ command. See examples below.
Note
Do not forget to commit migrations into repository! They’re created in migrations/ directory of the application they’re crated for
New field added to the model, or modified existing field in lfs.customer:
$ bin/django schemamigration lfs.customer --auto
New model added to lfs.catalog:
$ bin/django schemamigration lfs.customer --auto
Execute migration that was just created with ‘schemamigration’:
$ bin/django schemamigration lfs.customer --auto
$ bin/django migrate lfs.customer
Correct migration instead of creating new one, eg. if you’ve created a migration and then realized that your model still has to be corrected (see more here):
$bin/django schemamigration lfs.customer --auto --update
There are two preferred ways to contribute translations:
If your are a (Django-)developer you might want to fork django-lfs and lfs-theme on GitHub add the translations as used to, commit them and send us a pull request.
Note
Please make sure to fork the correct version branch.
If your are a translator you can just go to transifex, choose or add the language of your choice and start to translate via the web interface. Once you are ready we would add your translations to the source code.
Note
Please make sure to use the correct version.
If none of these fit your workflow you can of course just send us the translation files.
lfs.criteria.models.
Criterion
¶Base class for all criteria.
Attributes:
Constants:
get_value_type
.A list of operators which can be returned from get_operators
.
[
[EQUAL, _(u"Equal to")],
[LESS_THAN, _(u"Less than")],
[LESS_THAN_EQUAL, _(u"Less than equal to")],
[GREATER_THAN, _(u"Greater than")],
[GREATER_THAN_EQUAL, _(u"Greater than equal to")],
]
A list of operators which can be returned from get_operators
.
[
[IS_SELECTED, _(u"Is selected")],
[IS_NOT_SELECTED, _(u"Is not selected")],
]
A list of operators which can be returned from get_operators
.
[
[IS_VALID, _(u"Is valid")],
[IS_NOT_VALID, _(u"Is not valid")],
]
A list of operators which can be return from get_operators
.
[
[EQUAL, _(u"Equal to")],
[CONTAINS, _(u"Contains")],
]
get_operators
()¶Returns the selectable operators of the criterion which are displayed to the shop manager. This is a list of list, whereas the the first value is integer, which is stored within the criterion and the second value is the string which is displayed to the shop manager, e.g.:
[
[0, _(u"Equal to")],
[1, _(u"Less than")],
[2, _(u"Less than equal to")],
[3, _(u"Greater than")],
[4, _(u"Greater than equal to")],
]
Note
You can use one of the provided class attributes, see above.
get_selectable_values
(request)¶Returns the selectable values as a list of dictionary, see below. This
is only called when get_value_type
returns SELECT or
MULTIPLE_SELECT.
[
{
"id": 0,
"name": "Name 0",
"selected": False,
},
{
"id": 1,
"name": "Name 1",
"selected": True,
},
]
get_template
(request)¶Returns the template to render the criterion.
get_value_type
()¶Returns the type of the selectable values field. Must return one of:
get_value
()¶Returns the current value of the criterion.
is_valid
(request, product=None)¶Returns True
if the criterion is valid otherwise False
.
render
(request, position)¶Renders the criterion as html in order to displayed it within the management form.
update
(value)¶Updates the value of the criterion.
Parameters:
lfs.plugins.
OrderNumberGenerator
¶Base class from which all order number generators should inherit.
Attributes:
cart
The current cart of the customer.
customer
The customer of the order.
order
The order for which a new number is generated.
request
The current request
user
The user of the order.
get_form
(**kwargs)¶Returns the form which is used within the shop preferences management interface.
All parameters are passed to the form.
get_next
(formatted=True)¶Returns the next order number as string. Derived classes must implement this method.
Parameters:
%04d
.exclude_form_fields
()¶Returns a list of fields, which are excluded from the model form, see
also get_form
.
init
(request, order)¶Initializes the order number generator. This method is called automatically from LFS.
lfs.plugins.
PaymentMethodProcessor
(request, cart=None, order=None)¶Base class from which all 3rd-party payment method processors should inherit.
Attributes:
get_create_order_time
()¶Returns the time when the order should be created. It is one of:
get_pay_link
()¶Returns a link to the payment service to pay the current order, which is displayed on the thank-you page and the order confirmation mail. In this way the customer can pay the order again if something has gone wrong.
process
()¶Implements the processing of the payment method. Returns a dictionary with several status codes, see below.
Return Values:
This values are returned within a dictionary.
False
the customer keeps on the checkout page and gets
message
(if given) below. If this is True
the customer will
be redirected to next_url (if given).lfs.plugins.
PriceCalculator
(request, product, **kwargs)¶This is the base class that pricing calculators must inherit from.
Attributes:
get_base_price
(with_properties=True)¶Returns the base price of the product.
Parameters:
get_base_price_net
(with_properties=True)¶Returns the net base price of the product.
Parameters:
get_base_price_gross
(with_properties=True)¶Returns the gross base price of the product.
Parameters:
get_base_packing_price
(with_properties=True)¶Returns the base packing price of the product.
Parameters:
get_base_packing_price_net
(with_properties=True)¶Returns the base packing net price of the product.
Parameters:
get_base_packing_price_gross
(with_properties=True)¶Returns the base packing gross price of the product.
Parameters:
get_customer_tax
(with_properties=True)¶Returns the calculated tax for the current customer and product.
Parameters:
get_customer_tax_rate
()¶Returns the tax rate for the current customer and product.
get_effective_price
()¶Effective price is used for sorting and filtering. Usually it is same as value from get_price but in some cases it might differ (eg. if we add eco tax to product price)
get_for_sale_price
(with_properties=True)¶Returns the sale price for the product.
Parameters:
get_for_sale_price_net
(with_properties=True)¶Returns the sale net price for the product.
Parameters:
get_for_sale_price_gross
(with_properties=True)¶Returns the sale net price for the product.
Parameters:
get_price
(with_properties=True)¶Returns the stored price of the product without any tax calculations. It takes variants, properties and sale prices into account, though.
Parameters:
get_price_net
(with_properties=True)¶Returns the net price of the product.
Parameters:
get_price_gross
(with_properties=True)¶Returns the real gross price of the product. This is the base of all price and tax calculations.
Parameters:
get_standard_price
(with_properties=True)¶Returns always the stored standard price for the product. Independent
whether the product is for sale or not. If you want the real price of
the product use get_price
instead.
Parameters:
get_standard_price_net
(with_properties=True)¶Returns always the standard net price for the product. Independent
whether the product is for sale or not. If you want the real net price
of the product use get_price_net
instead.
Parameters:
get_standard_price_gross
(with_properties=True)¶Returns always the gross standard price for the product. Independent
whether the product is for sale or not. If you want the real gross
price of the product use get_price_gross
instead.
Parameters:
get_product_tax
(with_properties=True)¶Returns the calculated tax for the current product independent of the customer.
get_product_tax_rate
()¶Returns the stored tax rate of the product. If the product is a variant it returns the parent’s tax rate.
price_includes_tax
()¶Returns True if stored price includes tax. False if not.
lfs.plugins.
ShippingMethodPriceCalculator
(request, shipping_method)¶Base class from which all 3rd-party shipping method prices should inherit.
Attributes:
get_price
()¶Returns the stored price without any calculations.
get_price_gross
()¶Returns the gross price of the shipping method.
get_price_net
()¶Returns the net price of the shipping method.
get_tax
()¶Returns the total tax of the shipping method.
get_tax_rate
()¶Returns the tax rate of the shipping method.
These are settings specific for LFS which can be changed within
lfs_project/settings
. For Django’s default settings which are also relevant
for LFS, please visit Django settings for an explanation.
The class which is responsible for the creation of order numbers. LFS ships
with: lfs_order_numbers.models.OrderNumberGenerator
.
List of list of available 3rd-party payment method processors, whereas the first entry is the dotted name to a PaymentMethod and the second entry is the name, which is displayed. These are provided for selection within the payment method management interface, e.g.:
LFS_PAYMENT_METHOD_PROCESSORS = [
["acme.ACMEPaymentMethod", _(u"ACME payment")],
]
See also
List of list of available price calculators, whereas the first entry is the dotted name to a PriceCalculator and the second entry is the name, which is displayed. These are provided for selection within the shop preferences and the product. LFS is shipped with following entries:
LFS_PRICE_CALCULATORS = [
["lfs.gross_price.GrossPriceCalculator", _(u"Price includes tax")],
["lfs.net_price.NetPriceCalculator", _(u"Price excludes tax")],
]
List of list of available shipping method price calculators, whereas the first entry is the dotted name to a ShippingMethodPriceCalculator and the second entry is the name, which is displayed. These are provided for selection within the shipping method. LFS is shipped with following entries:
LFS_SHIPPING_METHOD_PRICE_CALCULATORS = [
["lfs.shipping.GrossShippingMethodPriceCalculator", _(u'Price includes tax')],
["lfs.shipping.NetShippingMethodPriceCalculator", _(u'Price excludes tax')],
]
lfs_added_to_cart
, which displays the last
product, which has been added to the cart. A reasonable alternative is
lfs_checkout_dispatcher
, which redirects directly to the checkout view.List of list of available criteria, whereas the first entry is the dotted name to a criterion and the second entry is the name of the criterion, which is displayed to the users. These criteria are provided to a shop manager for selection for on several locations. LFS is shipped with following criteria:
LFS_CRITERIA = [
["lfs.criteria.models.CartPriceCriterion", _(u"Cart Price")],
["lfs.criteria.models.CombinedLengthAndGirthCriterion", _(u"Combined Length and Girth")],
["lfs.criteria.models.CountryCriterion", _(u"Country")],
["lfs.criteria.models.HeightCriterion", _(u"Height")],
["lfs.criteria.models.LengthCriterion", _(u"Length")],
["lfs.criteria.models.WidthCriterion", _(u"Width")],
["lfs.criteria.models.WeightCriterion", _(u"Weight")],
["lfs.criteria.models.ShippingMethodCriterion", _(u"Shipping Method")],
["lfs.criteria.models.PaymentMethodCriterion", _(u"Payment Method")],
]
See also
True
.True
.Sets the locale for the shop, which is the base for number formatting and the displayed currency. If you don’t set it, the current locale of your Python is not touched at all. Example:
LFS_LOCALE = "en_US.UTF-8"
Extra states for orders, eg. if you need to mark order as Delivered or such. Should be list of tuples, each containing id and label. Note that id should start from high number (20 or higher) to avoid conflicts if some new ORDER_STATES are added to LFS core. Example value might be: [(20, _(‘Delivered’))]
There is a signal: order_state_changed that is sent when order state was changed and can be used for some special processing.
def handle_order_state_changed(sender, order, request, old_state, **kwargs):
pass
order_state_changed.connect(handle_order_state_changed)
lfs.checkout.forms.OnePageCheckoutForm
.True
.During checkout it is possible to not fill in one of the addresses - it will be then copied from another one.
By default Shipping address is same as Invoice address, but it can be changed with this setting.
Possible values are: shipping
and invoice
. Default is shipping
.
Note that you’ll have to manually change checkout page template and lfs.js if you change it to invoice
.
By default checkout_form (used at one_page_checkout.html) has method: no_address_field
that will return either
no_shipping
or no_invoice
field, depending on this setting.
lfs.addresses.models.Address
.lfs.addresses.forms.InvoiceAddressForm
.lfs.addresses.forms.ShippingAddressForm
.See also
False
.True
.True
.False
.False
.False
.LFS provides few management methods that should be used to keep your LFS instance clean. These are:
Calls all LFS cleanup commands at once. Detailed definition of other cleanup commands can be found below.
$ bin/django lfs_cleanup
LFS creates Customer object for each customer that adds something to the cart. Sometimes these customers do not proceed to the checkout so these Customer objects become useless. This command removes unnecessary customer objects from database. You can run in with cron.daily.
$ bin/django cleanup_customers
LFS creates Address objects in a number of places. These are bound to the customer or to the order. Sometimes it is possible that Address objects become orphans (eg. when Customer object is removed by not using cleanup_customers command). This command removes unnecessary address objects.
$ bin/django cleanup_addresses
LFS creates Cart objects when customers need to add something to the cart. These objects become unnecessary at some point and it makes no sense to hold them forever. This command removes old carts
$ bin/django cleanup_carts
In this how-to you will learn how to add own addresses to LFS, or better yet, how to adapt the address fields to your needs.
You can download the example application
here.
First you need to create a default Django application (or use an existing one), where you can put in your plugin. If you do not know how to do this, please refer to the excellent Django tutorial.
The main part of the application consists of a address model which must inherit
from the BassAddress
class.
from lfs.addresses.models import BaseAddress
class MyAddress(BaseAddress):
values_before_postal = ("firstname+", "lastname+", "company_name")
values_after_postal = ("phone", "email")
company_name = models.CharField(_("Company name"), max_length=50, blank=True, null=True)
phone = models.CharField(_("Phone"), blank=True, max_length=20)
mobile = models.CharField(_("Mobile"), blank=True, max_length=20, required=False)
email = models.EmailField(_("E-Mail"), blank=True, null=True, max_length=50)
In this case we add an extra field mobile
to LFS’ default address. In
generell you can add as many fields as you need.
The only LFS specific thing you have to take care of are two attributes:
values_before_postal
and values_after_postal
, which define the fields,
which are displayed before and after the postal address fields. This is used
when the address is diplayed within LFS, e.g. within the orders or the customer
management interface. If you add an +
at the end of the attribute there will
be no div
around the value. In this ways you can display fields in one row.
Another important part is to add the form, which is displayed to the shop
customer when he needs to enter his address. To makes things eaysier you should
inherit from AddressBaseForm
# django imports
from django import forms
# lfs imports
from lfs.addresses.models import AddressBaseForm
# my_addresses imports
from my_addresses.models import MyAddress
class MyAddressForm(AddressBaseForm):
fields_before_postal = ("firstname", "lastname", "company_name")
fields_after_postal = ("phone", "mobile", "email")
class Meta(AddressForm.Meta):
model = MyAddress
The only LFS specific thing you have to take care of are two attributes:
fields_before_postal
and fields_after_postal
which define the fields
which are displayed before and after the postal address fields. This is used
when the form is displayed within LFS, e.g. within the checkout page or within
the my addresses
section.
Now, as the code is ready, you can easily plug in your own address:
Add your application to the PYTHONPATH
Add your application to settings.INSTALLED_APPS (before lfs_theme
if
you overwrite the default templates):
INSTALLED_APPS = (
...
"my_addresses",
)
Add the model to the LFS_ADDRESS_MODEL setting:
LFS_ADDRESS_MODEL = "my_addresses.models.MyAddress"
Add the forms to the LFS_INVOICE_ADDRESS_FORM and LFS_SHIPPING_ADDRESS_FORM setting:
LFS_INVOICE_ADDRESS_FORM = "my_addresses.forms.MyInvoiceAddressForm"
LFS_SHIPPING_ADDRESS_FORM = "my_addresses.forms.MyShippingAddressForm"
As the address is a new model, you have to synchronize your database:
$ bin/django syncdb
Restart your instance and the address should be displayed to the shop users for instance within the checkout page.
You can provide different templates to render the addresses. By default LFS
tries try to get the specific template (address_view.html
). If it doesn’t
exist, it tries to get one of the specific templates
(invoice_address_view.html
or shipping_address_view.html
).
You can provide different templates to render the address forms. By default
LFS tries try to get the specific template (address_form.html
). If it
doesn’t exist, it tries to get one of the specific templates
(invoice_address_form.html
or shipping_address_form.html
).
By default LFS automatically updates default addresses to the values from last order. It is possible to change this behavior by setting
LFS_AUTO_UPDATE_DEFAULT_ADDRESSES
to False.
In this how-to you will learn how to add your own templates for categories and products.
The content of products and categories are rendered by templates. LFS ships with several default templates and you can add your own.
All registered templates for categories can be selected within the View
tab
of the Category Management Interface. All registered templates for products
can be selected within the Data
tab of the Product Management
interface.
Please refer to the default templates in order to find out which information are provided within the templates. You can also add your customer template tags in order to provide more functionality.
In order to add a new template for categories go to lfs.catalog.settings
and
add tuple to CATEGORY_TEMPLATES
.
(0,{"file":"%s/%s" % (CAT_PRODUCT_PATH ,"default.html"),
"image":IMAGES_PATH + " /product_default.png",
"name" : _(u"Category with products"),
}),
Which means:
CAT_PRODUCT_PATH
means this is a
template which displays the products of a category.(1,{"file": "%s/%s" % (CAT_CATEGORY_PATH ,"default.html"),
"image": IMAGES_PATH + "/category_square.png",
"name": _(u"Category with subcategories"),
}),
Which means:
CAT_PRODUCT_PATH
means this is a
template which displays the sub categories of a category.In order to add a new template for products go to lfs.catalog.settings
and
add tuple to PRODUCT_TEMPLATES
.
(0, {"file" : "%s/%s" % (PRODUCT_PATH, "product_inline.html"),
"image" : IMAGES_PATH + "/product_default.png",
"name" : _(u"Default template")
},),
Which means:
In this how-to you will learn how to add a own payment processor.
First you need to create a default Django application (or use an existing one), where you can put in your plugin. If you do not know how to do this, please refer to the excellent Django tutorial.
PaymentMethodProcessor
class¶The main part of the plugin consists of a class which must provide a certain API.
Create a class which inherits from lfs.plugins.PaymentMethodProcessor
:
from lfs.plugins import PaymentMethodProcessor
class MyPaymentMethodProcessor(PaymentMethodProcessor):
pass
process
method¶def process(self):
total = self.order.price
return {
"accepted": True,
"next_url": "http://www.acme.com/payment?id=4711&total=%s" % total,
}
This method is called from LFS when the shop customer submits the checkout page (while selected this payment method). Within that method you can do whatever it is necessary to process your payment, e.g.:
The process
method must return a dictionary with following keys (most of
them are optional):
False
the customer keeps on the checkout page and gets the
message
below. If this is True
the customer will be redirected to
next_url or to LFS’ thank-you pageget_create_order_time
method¶from lfs.plugins import PM_ORDER_IMMEDIATELY
def get_create_order_time(self):
return PM_ORDER_ACCEPTED
This method is called from LFS to determine when the order is to be created and must return one of following values:
get_pay_link
method¶In order to provide a link to the customer to re-visit the payment provider and
pay his order (if something did go wrong) LFS calls get get_pay_link method
or your class (this is optional).
def get_pay_link(self):
return "http://www.acme.com/payment?id=4711&total=%s" % total
Following all pieces are sticked together to the complete plugin:
from lfs.plugins import PaymentMethodProcessor
from lfs.plugins import PM_ORDER_IMMEDIATELY
class ACMEPaymentMethodProcessor(PaymentMethodProcessor):
"""
Implements the ACME payment processor.
"""
def process(self):
return {
"accepted": True,
"next_url": self.get_pay_link(),
}
def get_create_order_time(self):
return PM_ORDER_IMMEDIATELY
def get_pay_link(self):
total = self.order.price
return "http://www.acme.com/payment?id=4711&total=%s" % total
In this example the order is created immediately and the customer is redirected
to the ACME page in order to pay his order. After he has paid he might be
redirected to the thank-you
page of LFS, but this is completely up to ACME.
However, if something goes wrong while he is paying he can always go back to
ACME to pay his order because he gets the pay link via the order confirmation
mail.
Now as the code is ready, you can easily plugin your payment method:
module
field.type
of your payment method. Following types are provided:Within the PaymentMethodProcessor
request, the current order or the
current cart are available as instance variables:
self.request
self.cart (only when get_create_order_time returns PM_ORDER_ACCEPTED)
self.order (only when get_create_order_time returns PM_ORDER_IMMEDIATELY)
When an external payment processor redirects to LFS the current order is still in the session. This means you can redirect to an own view and set the order state to PAID, for instance:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from lfs.plugins import PAID
def acme_callback_success_view(request):
order = request.session.get("order")
order.state = PAID
order.save()
return HTTPRedirectResponse(reverse("lfs_thank_you"))
All fields of the checkout form are available within the process
method
via the request variable, e.g.:
request.POST.get("invoice_firstname")
In this tutorial you will learn how to your own custom product pricing module.
First you need to create a default Django application (or use an existing one). If you do not know how to do this, please refer to the excellent Django tutorial.
Within __init__.py
file of your application (or anywhere you choose) create
a class that inherits from lfs.plugins.PricingCalculator and implement all
inherited methods.
from lfs.plugins import PriceCalculator
class CustomPriceCalculator(PriceCalculator):
def get_price(self, with_properties=True):
return self.get_price_net()
... Other Methods...
LFS_PRICE_CALCULATORS = [
["lfs.gross_price.GrossPriceCalculator", _(u"Price includes tax")],
["lfs.net_price.NetPriceCalculator", _(u"Price excludes tax")],
["mycustom_price.CustomPriceCalculator", _(u"My Pricing Calculator")],
]
Shop / Preferences
.Default Values
and go the Price Calculator
section.Note
All products with an unset price calculator will default to using the shop price calculator.
Catalog / Product
.Data Tab
and scroll to the Prices
section.Save Data
.Address localization is turned on by default in LFS. To turn off Address l10n in settings.py set:
POSTAL_ADDRESS_L10N = False
If you wish to customize the address labels and whether the address line is required or not, you can add the following variables to settings.py:
POSTAL_ADDRESS_LINE1, POSTAL_ADDRESS_LINE2, POSTAL_ADDRESS_CITY,
POSTAL_ADDRESS_STATE, POSTAL_ADDRESS_CODE
Each of these variables is set to a tuple of the format:
('label', True/False)
label
is used to label the field, and the second boolean value sets whether
the field is required or not, e.g.:
POSTAL_ADDRESS_LINE1 = ("Department", True)
LFS provides a generic export engine for products (see here for more). In this tutorial you will learn how to create your own scripts to format the data like you want to.
First you need to create a default Django application (or use an existing one). If you do not know how to do this, please refer to the excellent Django tutorial.
Within the __init__.py of your application create a function that will return the products, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # python imports
import csv
# django imports
from django.http import HttpResponse
from django.core.mail import send_mail
# lfs imports
from lfs.export.utils import register
def export(request, export):
"""Export method for acme.com
"""
response = HttpResponse(mimetype="text/csv")
response["Content-Disposition"] = "attachment; filename=acme.txt"
writer = csv.writer(response, delimiter=";", quotechar='"', quoting=csv.QUOTE_ALL)
for product in export.get_products():
writer.writerow(product.id, product.get_name())
return response
register(export, "acme.com")
|
get_products
method of the
passed export object.Now go Utils / Export
within the LFS Management Interface, create a new
export, select the products and your newly script and call it via the Export
button. (See here for more).
In this how-to you will learn how to add new Actions Groups
and how to use
them within your templates.
Login as admin.
Go to Django’s admin interface:
http://localhost:8000/admin/
Go to Core / Action groups
.
Click on the Add Action Group
button.
Enter the name of the group, e.g. Sidebar
.
Insert the actions
tag to your template as following:
{% actions Sidebar %}
{% for action in actions %}
<div>
<a href="{{ action.link }}">
{{ action.title }}
</a>
</div>
{% endfor %}
Note
We pass the above given group name to the actions
tab. In this case
Sidebar
.
In this how-to you will learn how to create a theme for LFS.
Note
You can download the whole theme here
.
First you have to create a new Django application. This is beyond the purpose of this tutorial and you should refer to Django’s excellent tutorial if you want to learn more.
In short, your starting file structure should look like this:
mytheme
__init__.py
templates
lfs
Register mytheme to Django’s template engine.
Move the mytheme folder to the PYTHONPATH.
The easiest way to do that is to put it into the lfs_project folder of the buildout.
Register the theme
Add mytheme to INSTALLED_APPS before lfstheme:
INSTALLED_APPS = (
...
"mytheme",
"lfstheme",
"django.contrib.admin",
...
Now copy the templates you want to change into the lfs folder of mytheme and adapt them to your needs.
Important: you have to keep the original path, e.g: base.html must be within the root of the lfs folder whereas the cart portlet (cart.html) must be within the portlets folder:
mytheme
__init__.py
templates
lfs
base.html
portlets
cart.html
To use own CSS several steps are necessary.
Create a static
folder within mytheme:
mytheme
static
...
Within that create a new CSS-file, e.g. mytheme.css and add your CSS rules, e.g.:
.breadcrumbs li {
color: red !important;
}
Alternatively you might copy main.css from lfstheme
and adapt it to your
needs.
Go to the lfs_project/media
folder and create a symbolic link to the
static folder:
$ ln -s <path/to/buildout>/lfs_project/mytheme/static mytheme
Copy base.html to mytheme/templates/lfs (if you haven’t done it so far)
Include your CSS file to the header:
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}mytheme/mytheme.css">
Optionally delete the link to main.css (if you just want to use your own CSS).
LFS order numbers generator is pluggable. In this tutorial you will learn how to add an own one.
Please see also the complete example application
or refer to the default implementation
of LFS within lfs_order_numbers
.
First you need to create a default Django application (or use an existing one). If you do not know how to do this, please refer to the excellent Django tutorial.
The structure of the application should look at least like this:
my_order_numbers
__init__.py
models.py
Within models.py
file of your application create a class called
OrderNumberGenerator
which inherits from LFS’ OrderNumberGenerator base
class and add a method to it called get_next
:
from lfs.plugins import OrderNumberGenerator as Base
class OrderNumberGenerator(Base):
def get_next(self, formatted=True):
return "DOE-4711"
The get_next
method is called when the shop customer submits a new order. It
must return a character value which will become the order number of the new
order.
Now as the code is ready, you can easily plugin your payment method:
Add your application to the PYTHONPATH.
Add your class to settings.py
LFS_ORDER_NUMBER_GENERATOR = “my_order_numbers.models.OrderNumberGenerator”
Add your application to settings.INSTALLED_APPS and sync the database.
You should now see your form within the Order Numbers
tab within
Shop/Preference
and the get_next
method of your model should be
called to generate a new order number.
Optionally you can add your own HTML for the management interface. For this just add the order_numbers_tab.html template to your application:
my_order_numbers
templates
manage
order_numbers
order_numbers_tab.html
Please refer to the standard template of LFS to get more details. You can find this on following place:
lfs/templates/manage/order_numbers/order_numbers_tab.html
In this case please make sure that your my_order_numbers
application
stands before lfs
within INSTALLED_APPS
of settings.py
so
that LFS’ default order_numbers_tab.html
template is overwritten.
get_form
method. See the API
for more.exclude_form_fields
. The return value is just
passed to the exclude attribute of the from Meta class. See the API for
more.Within the get_next
method of your new class you have access to following
information:
Please note that you have also access to the products of the order via the
items
attribute. For instance:
for item in self.order.items.all():
product = item.product
See the also the Order
and OrderItem
classes for more information.
In this how to you will learn how to add your own shipping price calculator.
First you need to create a default Django application (or use an existing one), where you can put in your plugin. If you do not know how to do this, please refer to the excellent Django tutorial.
ShippingMethodPriceCalculator
class¶The main part of the plugin consists of a class which must provide a certain API.
Create a class which inherits from lfs.plugins.ShippingMethodPriceCalculator
:
from lfs.plugins import ShippingMethodPriceCalculator
class MyShippingMethodPriceCalculator(ShippingMethodPriceCalculator):
pass
get_price_net
and get_price_gross
methods¶This methods are called from LFS to display the shipping price or to calculate the total price of the cart or order.
def get_price_net(self):
# This doesn't make much sense, but the net price is always 11.0
return 11.0
def get_price_gross(self):
return 11.0 * ((100 + self.shipping_method.tax.rate) / 100)
Following all pieces are sticked together to the complete plugin:
from lfs.plugins import ShippingMethodPriceCalculator
class MyShippingMethodPriceCalculator(ShippingMethodPriceCalculator):
def get_price_net(self):
# This doesn't make much sense, but the net price is always 11.0
return 11.0
def get_price_gross(self):
return 11.0 * ((100 + self.shipping_method.tax.rate) / 100)
Now as the code is ready, you can easily plugin your shipping method price calculator:
price_calculator
field.Within the ShippingMethodPriceCalculator
the current request and the
shipping method are available as instance variables:
self.request
self.shipping_method
With the request
you have access to the current cart (in case you need
it):
from lfs.cart.utils import get_cart
cart = get_cart(self.request)
With the request
you have access to the current customer (in case you need
it):
from lfs.customer.utils import get_customer
customer = get_customer(self.request)
LFS ships with main package of TinyMCE that doesn’t contain any translation files. It is easy to use internationalized version of TinyMCE by adding few things into your theme.
Download TinyMCE
Go to TinyMCE website and download TinyMCE x.x jQuery package
Extract TinyMCE into your theme
Extract downloaded TinyMCE
into your Theme, e.g. theme/static/manage/tiny_mce_x_x/
Download TinyMCE language file(s)
Go to TinyMCE website and download language file(s) that you need
Extract TinyMCE language files into your theme
Go to folder where you’ve just extracted main package of TinyMCE, e.g.: theme/static/manage/tiny_mce_x_x/
and extract language files into proper directories.
Copy manage_base.html
to your theme
Copy lfs/templates/manage/manage_base.html
to your theme: mytheme/templates/manage/manage_base.html
Copy lfs_tinymce.js
to your theme
Copy lfs/static/js/lfs_tinymce.js
to your theme: mytheme/static/js/lfs_tinymce.js
(if you use different path then you have to update it at manage_base.html in step 7)
Modify lfs_tinymce.js
(copy located at your theme)
Change/add highlighted parts of TinyMCE initialization script:
// Theme options
$(selector).tinymce({
// Location of TinyMCE script
script_url : '/static/manage/tiny_mce_x_x/tiny_mce.js',
// General options
theme : "advanced",
plugins : "safari,save,iespell,directionality,fullscreen,xhtmlxtras,media",
theme_advanced_buttons1 : buttons,
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
save_onsavecallback : "save",
relative_urls : false,
cleanup : false,
height : height,
language : LFS_LANGUAGE,
content_css : "/static/css/tinymce_styles.css",
setup : function(ed) {
ed.addButton('image', {
onclick : function(e) {
imagebrowser(e, ed);
}
});
}
});
Customize manage_base.html
at your theme
Replace:
<script type="text/javascript" src="{{ STATIC_URL }}tiny_mce-3.4.2/jquery.tinymce.js"></script>
with (use path to TinyMCE folder that you created in step 2):
<script type="text/javascript" src="{{ STATIC_URL }}manage/tiny_mce_x_x/jquery.tinymce.js"></script>
Add following code to <head> section:
<script type="text/javascript">
var LFS_LANGUAGE = '{{ LANGUAGE_CODE|lower }}';
</script>
Note that for some languages LANGUAGE_CODE
used by Django may differ from language code used by TinyMCE.
For such cases you’ll probably have to write your own tag/filter that will map Django’s language code to TinyMCE’s
language code (or you’ll just hard code it).
In this how-to you will learn how to add own criteria to LFS.
The goal in this how-to is to create a criterion, for which the shop manager can enter a SKU and decide (via operators) whether the criterion is valid if the product with the entered SKU is within the cart or not.
You can download the example application
here.
First you need to create a default Django application (or use an existing one), where you can put in your plugin. If you do not know how to do this, please refer to the excellent Django tutorial.
The main part of the application consists of a criterion model which must
inherit from the Criterion
base class.
class ProductCriterion(Criterion):
value = models.CharField(max_length=100)
The only attribute we need is the value the shop manager will save for the criterion. The attribute can have any type you need. In this example we use a simple character field. The entered SKU is checked within the products in the cart. Dependent on the chosen operator the criteria is valid if the product is within the cart or not.
In the next steps we implement all necessary methods which are needed to make
the criterion work. In this case these are get_operators
and is_valid
.
The get_operators
method needs to return the available operators for this
criterion. It is a list of list, whereas the first value is an integer and the
second value is the name of the operator.
def get_operators(self):
return [
[0, _(u"Is in cart")],
[1, _(u"Is not in cart")],
]
The is_valid
method needs to return a boolean. If it returns True
the
criterion is considered valid, it returns False
the criterion is considered
not valid.
def is_valid(self):
if self.product:
return self.value == self.product.sku
elif self.cart:
result = any([self.value == item.product.sku for item in self.cart.get_items()])
return result if self.operator == 0 else not result
else:
return False
Note
Within the is_valid
method (as in all methods of the Criterion
class) following attributes are available:
- product
- This is only set, when the criterion is called from the product detail view otherwise it is
None
.- cart
- The current cart of the current user.
- request
- The current request.
Now as the code is ready, you can easily plugin your own criterion:
Add your application to the PYTHONPATH
Add your application to settings.INSTALLED_APPS and sync your database:
INSTALLED_APPS = (
...
"product_criterion",
)
Add the class to the LFS_CRITERIA setting:
LFS_CRITERIA = [
...
["product_criterion.models.ProductCriterion", _(u"Product Criterion")],
]
As all criteria are models, you have to synchronize your database:
$ bin/django syncdb
Restart your instance and the criterion should be available for selection, for instance within the discount criteria tab.
You should now see your criterion within the criteria tab of Discounts
for
instance. You can enter a product SKU to it and select one of the above
mentioned operators.
Country
criterion within
lfs.criteria.models
for more.lfs.criteria.models
to see how these
are implemented