Skip to main content

Category

A Category allows you to group and organize products. The main use case is to build up a navigation for your storefront, but also to categorise products making it easier to search for them.

Creating a category

Use the create method to create a new category:

1use Larasell\Larasell\Models\Category;
2
3$category = Category::create([
4    'name' => 'Clothing',
5    'slug' => 'clothing',
6]);

This creates a new top-level category. For simple stores, this is enough. Most likely you'll need nest categories. To do that you set a parent_id on the one you want to nest.

 1use Larasell\Larasell\Models\Category;
 2
 3$clothing = Category::create([
 4    'name' => 'Clothing',
 5    'slug' => 'clothing',
 6]);
 7
 8$shirts = Category::create([
 9    'name' => 'Shirts',
10    'slug' => 'shirts',
11    'parent_id' => $clothing->id,
12]);

Or you can use Laravel's children method to create a nested category:

 1use Larasell\Larasell\Models\Category;
 2
 3$clothing = Category::create([
 4  'name' => 'Clothing',
 5  'slug' => 'clothing',
 6]);
 7
 8$clothing->children()->create([
 9  'name' => 'Shirts',
10  'slug' => 'shirts',
11]);

Choose whatever fits your needs or style.

Adding products

A category without products is not useful. Use the attach method to add one:

 1use Larasell\Larasell\Models\Category;
 2use Larasell\Larasell\Models\Product;
 3
 4$category = Category::create([
 5    'name' => 'Clothing',
 6    'slug' => 'clothing',
 7]);
 8
 9$product = Product::create([
10    'name' => 'T-Shirt',
11    'price' => 1999,
12]);
13
14$product->categories()->attach($category->id);

In case you want to add multiple categories at once you can use the sync method:

 1use Larasell\Larasell\Models\Category;
 2use Larasell\Larasell\Models\Product;
 3
 4$clothing = Category::create([
 5    'name' => 'Clothing',
 6    'slug' => 'clothing',
 7]);
 8
 9$summer = Category::create([
10    'name' => 'Summer sale',
11    'slug' => 'summer-sale',
12]);
13
14$product = Product::create([
15    'name' => 'T-Shirt',
16    'price' => 1999,
17]);
18
19$product->categories()->sync([$clothing->id, $summer->id]);

Relationships and traversal

You often need to get other categories that are related to the one you currently got. Like getting the parent, descendants or sibling categories.

 1use Larasell\Larasell\Models\Category;
 2
 3// Get the parent category of a category
 4$shirts->parent->name->get(); // 'Clothing'
 5
 6// Get the sibling categories that share the same parent
 7$shirts->siblings;
 8
 9// Get the children of a category, useful for
10// rendering the next level of your navigation
11$clothing->children;
12
13// Get all descendant categories, including children of children
14$clothing->descendants;
15
16// Get all top-level categories. This is a good
17// starting point to build your storefront navigation
18Category::root()->get();

Removing products

To remove a product from a category, use the detach method:

1use Larasell\Larasell\Models\Category;
2use Larasell\Larasell\Models\Product;
3
4$product = Product::where('name->en', 'T-Shirt')->firstOrFail();
5$category = Category::where('slug->en', 'summer-sale')->firstOrFail();
6
7$product->categories()->detach($category->id);

Detaching multiple categories works the same way, pass an array of category ids:

1$product->categories()->detach([$clothing->id, $summer->id]);

If you call detach without any arguments, Larasell removes the product from all categories:

1$product->categories()->detach();

Detaching only removes the association between the product and the category. It doesn't delete the product or the category itself.

Translating the category

It's possible to translate certain fields of a category, like the name and slug.

1use Larasell\Larasell\Models\Category;
2
3Category::create([
4  'name' => ['en' => 'Clothing', 'de' => 'Kleidung'],
5  'slug' => ['en' => 'clothing', 'de' => 'kleidung'],
6]);

To get the translated value, you call the get method on the category. It uses App::currentLocale() to determine which translation to return to you.

1$category->name->get();
2$category->slug->get();

In case you want to get the translation for a specific locale, you can pass an optional string parameter to the method.

1$category->name->get('de');

If you try to get the value of a translation for a locale that does not exist, Larasell falls back to the locale defined in APP_FALLBACK_LOCALE of your .env file.

Translating an existing category is easy too.

1use Larasell\Larasell\Models\Category;
2
3$clothing = Category::where('slug->en', 'clothing')->first();
4
5$clothing->update([
6  'name' => ['nl' => 'Kleding']
7]);

Note that calling update as above overwrites all previous translations. If you only want to add a translation, you have to call the with method on the translatable value.

1$clothing->update(['name' => $clothing->name->with('fr', 'Vêtements')]);

In this case, we added a translation for French. If it already existed, we would overwrite the value rather than add it.

The same is true for removing a translation. Call the without method to remove a single translation without removing all translations.

1$clothing->update(['name' => $clothing->name->without('de')]);

The all method helps you see all the translations the category has.

1$clothing->name->all(); // ['en' => 'Clothing', 'nl' => 'Kleding', 'de' => 'Kleidung']

There's a has method that you can call to check whether a category has a translation for a specific locale.

1$clothing->name->has('pt');

Visibility

It's possible to define the visibility of a Category. Common use cases are preparing a new navigation structure or hiding seasonal categories from your storefront.

1use Larasell\Larasell\Enums\Visibility;
2use Larasell\Larasell\Models\Category;
3
4$category = Category::create([
5    'name' => 'Clothing',
6    'slug' => 'clothing',
7    'status' => Visibility::Hidden,
8]);

Then at a later point you can make it visible, and it will show up on the storefront.

1use Larasell\Larasell\Enums\Visibility;
2use Larasell\Larasell\Models\Category;
3
4$category = Category::where('slug->en', 'clothing')->first();
5
6$category->update([
7  'status' => Visibility::Visible // or pass 'visible'
8]);

A category can either be hidden or visible. If you want, you can just pass a string instead of passing the Visibility enum.