Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Products and variants documentation #2437

Merged
44 changes: 44 additions & 0 deletions guides/products-and-variants/multi-currency-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Multi-currency support

`Spree::Price` objects track a price for a specific currency and variant
combination. For example, if a variant is available for $15 USD or €7 EUR, that
variant would have two `Spree::Price` objects associated with it (one for each
currency).

<!-- TODO:
It looks like there are other circumstances where another a Spree::Price
object would be created in regards to currency. For example, if you sell your
products in EUR but sell them to multiple countries that have different VAT
rates.
-->

If none of a product's `Spree::Variant`s have a price value for the site's
configured currency, that product is not visible in the store frontend.

You can see a variant's price in the store's configured currency by calling the
`price` method on that instance:

```ruby
Spree::Variant.find(1).price
# => 15.99
```

You can also call the `price` method on a `Spree::Product`. If you call the
`price` method on a product, it gets the price of the product's master variant.

For a list of all of the `Spree::Price`s associated with a product or variant,
you can call the `prices` method on an instance of them:

```ruby
Spree::Product.find(1).prices
# => [#<Spree::Price id: 2 ...]
# [#<Spree::Price id: 3 ...]

Spree::Variant.find(1).prices
# => [#<Spree::Price id: 4 ...]
# [#<Spree::Price id: 5 ...]
```

<!-- TODO:
Some of this article could be repurposed for a new section about Spree::Price.
-->
94 changes: 94 additions & 0 deletions guides/products-and-variants/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Overview of products and variants

Products and variants are integral to Solidus. While the `Spree::Product` and
`Spree::Variant` models depend on each other, it is important to understand how
they are different:

- `Spree::Product`s track the general information about a product. This includes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're talking about products and variants here using the same terms. I think it would be best to start with examples of cases where a product has variants, and what the product is and what the variant is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are very right. I've extended the products and variants bullet points here.

the product description and the permalink where a customer would find the
product listing on a store. If you sell a mug and a t-shirt, you would set up
a separate product for each of them.
- `Spree::Variant`s track the specific information about a variant of that
product. For example, the variant provides the dimensions and weight. The
variant provides the information required by orders and shipments. If you sell
a red t-shirt and a green t-shirt, you could make each one a variant of your
t-shirt product. Similarly, if all of your t-shirts come in small, medium, and
large, then you would make additional variants for each of those: small green
t-shirt, small red t-shirt, medium green t-shirt, medium red t-shirt, and
so on.

The rest of this article introduces essential information for using products and
variants in Solidus.

<!-- TODO:
It might be worth diagramming how Spree::Products, Spree::Variants,
and Spree::LineItems affect an order and how it's priced.
-->

## Products

`Spree::Product`s track unique products within your store. If you sell a mug and
a t-shirt, you would set up a product for each of them.

If you have a number of items that are similar (like t-shirts that come in
small, medium, and large sizes), you can create [variants](#variants) for a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This information should come first to provide context about the information listed above.

single product instead of creating three separate products.

You can categorize products using [taxonomies and
taxons](#taxonomies-and-taxons). And, if you want to offer more extensive
information about a single product, you can add custom [product
properties](product-properties.md) for any product.

## Variants

`Spree::Variant`s track the unique properties of multiple similar products that
you sell. For example, if you sell a red mug and a green mug that have many
other properties in common, you could create a single product ("Mug") with two
variants.

Here are a few key points to note about variants:

- If a product has more than one variant, all variants require an option type
and option value. (For example, an option type of "Size" with the values
"Small", "Medium", and "Large".)
- Every product has a master variant. When additional variants are created, they
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A master variant is a complicated concept that should have additional information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a link to more information about master variants here. It lives in the variants.md article. I've extended that section as well. 👍 Thank you.

inherit properties from the master variant. The properties can be overridden
by the variant's own unique values. See [Master variants][master-variants] for
more information.
- All product images are linked to a product's variants. Product images are
either associated with a specific variant or can be used for all of the
variants.

For more information about variants, see the [Variants][variants] article.

[master-variants]: variants.md#master-variants
[variants]: variants.md

## Taxonomies and taxons

You can create categories for products using `Spree::Taxonomy`s and
`Spree::Taxon`s. The following taxonomies are common in ecommerce stores:

- Categories
- Brands

Where taxons act as subcategories to taxonomies:

```
Categories
|-- Luggage
|-- Clothing
|-- T-shirts
|-- Socks
|-- Shoes
Brands
|-- Adidas
|-- Bentley
|-- Calvin Klein
```

Taxons become associated with products via the `Spree::Classification` model.

For more detailed information about taxonomies and taxons, see the [Taxonomies
and taxons](taxonomies-and-taxons.md) article.

85 changes: 85 additions & 0 deletions guides/products-and-variants/product-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Product images

Product images belong to the `Spree::Image` model and belong to the variants of
a product. Solidus handles the creation and storage of images using
[Paperclip][paperclip-gem].

Take note of these product image properties:

- `viewable_id`: The ID for the variant that this image is linked to.
- `attachment_width` and `attachment_height`: The width and height of the
original image that was uploaded. See the [Paperclip
section](#paperclip-settings) of this article for more information about how
Solidus resizes product images.
- `position`: Sets the image's position in a list of images. For example, an
image with the `position` of `2` would be displayed after the image with the
`position` of `1`.
- `alt`: The alt text for an image. Administrators can add this from the
backend.

## Fallback images

Every product image is linked to the ID of a specific `Spree::Variant`. However,
if the variant is a master variant (the variant's `is_master` property equals
`true`) this image can be displayed as a fallback for other variants without
images.

If you want to change the image that is displayed when a product has no image,
you can override Solidus's [`noimage` defaults][solidus-noimage] in your project
by creating a `app/asets/images/noimages` directory.

If you have changed your [Paperclip configuration](#paperclip-settings), make
sure that you include `noimage` images for each of image attachment keys that
you have defined. The default keys are `mini`, `small`, `product`, and `large`.

## Images for all variants

Administrators can upload images when adding or editing a product in the
[`solidus_backend`][solidus-backend]. The images can be set to be displayed
for a specific variant or for **All** variants.

If set to **All**, the `viewable_id` is set to the master variant for the
current product.

## Paperclip settings

[Paperclip][paperclip-gem] handles the creation and storage of product images.
By default, it creates creates several version of each image at specific sizes.

You can check the default settings by calling the `attachment_definitions`
method on `Spree::Image` in your Rails console:

```shell
Spree::Image.attachment_definitions[:attachment][:styles]
=> {
mini=>"48x48>",
small=>"100x100>",
product=>"240x240>",
large=>"600x600>"
}
```

The default sizes can be changed in an initializer. For example, in your
`config/initializers/paperclip.rb` file. You can set new defaults like this:

```ruby
Spree::Image.attachment_definitions[:attachment][:styles] = {
mini: '128x128>',
small: '256x256>',
product: '512x512>',
large: '1024x1024>'
}
```

### Regenerate thumbnails

If you change the default image sizes, you must regenerate the Paperclip
thumbnails by running a Rake task:

```shell
bundle exec rake paperclip:refresh:thumbnails CLASS=Spree::Image
```

[paperclip-gem]: https://github.com/thoughtbot/paperclip
[solidus-backend]: https://github.com/solidusio/solidus/tree/master/backend
[solidus-noimage]: https://github.com/solidusio/solidus/tree/master/core/app/assets/images/noimage
43 changes: 43 additions & 0 deletions guides/products-and-variants/product-properties.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Product properties

Product properties belong to the `Spree::ProductProperty` model. They track
individual attributes for a product that would not apply to all of your
products. Typically, product properties would be used for additional product
information.

As an example, you might see a list of product properties for a limited edition
t-shirt as a table on its product page:

| Property name | Property value |
|---------------|------------------|
| Fit | Tapered |
| Manufacturer | American Apparel |
| Material | 100% cotton |

You can retrieve the value for a property on a `Spree::Product` object by
calling the `property` method on it and passing through that property's name:

```shell
Spree::Product.find(1).property("fit")
=> "Tapered"
```

You can set a property on a product by calling the `set_property` method:

```ruby
Spree::Product.find(1).set_property("fit", "Tapered")
```

If this property doesn't already exist, a new `Property` instance with this name
will be created.

## Product properties are not option types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point and needs further detail. When should I use a property, and when should I use an option type?


A product property should not be confused with an [option type][option-types],
which is used to define variants for a product.

Use product properties to describe a product: "The t-shirt is 100% cotton." Use
option types to show how variants are distinct from each other: "The t-shirt can
be purchased in one of two colors: red or green."

[option-types]: variants.md#option-types
49 changes: 49 additions & 0 deletions guides/products-and-variants/products.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Products

`Spree::Product`s track separate products within your store. If you sell a mug
and a t-shirt, you would set up a product for each of them.

Products have the following attributes:

- `name`: The short name for a product.
- `description`: The full description for your product.
- `slug`: An SEO-slug based on the product name. This slug is used in the
product's URL.
- `available_on`: The first date the product becomes available for sale online
in your shop. If you don't set the `available_on` attribute, the product does
not appear among your store's products for sale.
- `deleted_at`: The date the product is no longer available for sale in the
store.
- `meta_description`: A description targeted at search engines for search engine
optimization (SEO). This description is shown in search results and may be
truncated after 160 characters.
- `meta_keywords`: Comma-separated keywords and phrases related to the product,
also targeted at search engines.
- `meta_title`: Title to put in HTML `<title>` tag. If left blank, the product
name is used instead.
- `promotionable`: Determines whether or not promotions can apply to the
product. (Labeled "Promotable" in the admin interface.)

## Variants

Most of Solidus's product-related business logic belongs to `Spree::Variant`s
rather than products. This includes the product's price, dimensions, and product
images.

Even if your store only sells a single product that only comes in one size and
color, that product would have a single variant that handles the additional
properties.

For more information about variants, see the [variants](variants.md) article.

## Product properties

You can also configure products to have [product
properties](product-properties.md). Product properties allow you to add custom
product information for a single product.

A "Size" attribute would be used for many products and would be more useful as
an [option type](variants.md#option-types) for variants. However, if you decide
to sell a limited edition t-shirt you might want to add unique product
properties for marketing purposes - like "Fit", "Material", and "Manufacturer".

Loading