Categories are an important part of WordPress and WooCommerce solutions. They give an opportunity to group similar items together. If you are using WordPress as a CMS for your online shop, chances are you will need the WooCommerce plugin to manage your products.
Using standard free plugins is time consuming. Working with WooCommerce inside WordPress is a lot of work: first you need to create all your products and then publish them inside posts or pages. The complexity rises if you target several countries with different varieties of the same products.
Automating the process is the answer. Both WordPress and WooCommerce offer their own REST APIs that you can use to automate product creation and publishing: WordPress Rest API, WooCommerce Rest API.
There is a difference between WordPress and WooCommerce categories. They are both Terms in the WP database, but have different taxonomies: “category” for WordPress and “product_cat” for WooCommerce.
In order to fetch and save categories through WordPress Rest API in C# we have chosen the library WordPressPCL. No need to reinvent the wheel if there are libraries out there that you can adjust to your own needs and contribute in the process.
To begin with, we used the WordPressSharp library, which uses the XML-RPC WordPress interface. It didn’t want to work with categories, so we switched over to WordPressPCL. It is incomplete, but is open source. To get WordPressPCL to work with WordPress categories, we had to extend it. There we’ll publish the code after some polishing.
The process of getting the categories in C# with WordPressPCL is as follows:
WordPressClient _wprest = new WordPressClient($"{base_url}/wp-json/"); _wprest.Username = user; _wprest.Password = pass;
public List<WordPressPCL.Models.Category> GetCategories() { List<WordPressPCL.Models.Category> cats = null; if (_wprest != null) { Task.Run(() => { var cat_task = _wprest.ListCategories(); cat_task.Wait(); cats = cat_task.Result.ToList(); }).Wait(); } return cats; }
<UserControl x:Class="mywoo.WpCategories" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:woo_pdf.PDF" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="120"> <Grid > <TreeView x:Name="treeCategories" ItemsSource="{Binding}" > </TreeView> </Grid> </UserControl>
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local_woo="clr-namespace:mywoo" mc:Ignorable="d" Name="MyWoo" Height="692.084" Width="715.226"> <Grid> <local_woo:WpCategories MinHeight="200" x:Name="wpcats_post"/> </Grid> </Window>
var cats = GetCategories(); wpcats_post.SetCategories(cats); public void SetCategories(List<WordPressPCL.Models.Category> cats) { var parents = cats.Where(p => p.ParentId == 0); foreach (var c in parents) { var children = find_children(c, cats); var p = MakeTreeViewItem(c); foreach (var child in children) { child.Items.Add(d); } treeCategories.Items.Add(p); } }
Resulting categories look almost the same as in WordPress:
The process of saving chosen categories for the post with WordPressPCL is as follows:
var selectedCategories = wpcats_post.SelectedCategories(); public List<int> SelectedCategories() { return _selected; }
Variable _selected
is a list holding all our checked categories. In order to populate the list you will need to implement the Click-event
for C# CheckBox
.
List<Term> categoriesList = new List<Term>(); foreach (int id in selectedCategories) { Term term = _wp.GetTerm("category", id); categoriesList.Add(term); }
var post = new Post { PostType = "post", Status = "draft", Title = title, Content = contents, PublishDateTime = DateTime.Now, ModifiedDateTime = DateTime.Now, Terms = categoriesList.ToArray(), }; _wprest.NewPost(post);
As mentioned earlier WooCommerce operates with it’s own categories. Taxonomy name is “product_cat” in the WordPress “wp_term_taxonomy” database table.
Working with product categories will require use of the Woocommerce Rest API. It is a well documented API with consumer libraries like WooCommerceNET that are being actively developed and maintained.
Using WooCommerceNET in C# .NET project is straightforward. Here is a simple tutorial on how to use WooCommerceNET API consumer.
RestAPI rest = new RestAPI(url, key, secret); WCObject wc = new WCObject(rest);
public async Task<List<ProductCategory>> GetWooCommerceCategories() { try { var prod_cats = await wc.GetProductCategories(); return prod_cats; } catch { } return new List<ProductCategory>(); }
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:mywoo" mc:Ignorable="d" Name="MyWoo" Height="692.084" Width="715.226"> <Grid> <local:WpCategories x:Name="wpcats" /> </Grid> </Window>
var prod_cats = ProductCategories(); SetCategories(prod_cats); public List<ProductCategory> ProductCategories() { List<ProductCategory> prod_cats = new List<ProductCategory>(); var t = Task.Run(async () => { prod_cats = await GetWooCommerceCategories(); }); t.Wait(); return prod_cats; } public void SetCategories(List<WooCommerceNET.WooCommerce.ProductCategory> prod_cats) { var parents = prod_cats.Where(p => p.parent == 0); foreach (var c in parents) { var children = find_children(c, prod_cats); var p = MakeTreeViewItem(c); foreach (var d in children) { p.Items.Add(d); } treeCategories.Items.Add(p); } }
The process of saving selected categories for the product is almost the same as for post categories with WordPress.
List<int> selectedProductCategories = wpcats.SelectedCategories(); public List<int> SelectedCategories() { return _selected; }
List<WooCommerce.Category> categoriesList = new ListWooCommerce.Category>(); foreach (int id in selectedCategories) { var cat = GetProductCategory(id); var simple_cat = new WooCommerce.Category { id = cat.id, name = cat.name, slug = cat.slug }; categoriesList.Add(simple_cat); }
Product p = new Product() { name = name, regular_price = 0, type = "external", button_text = "Free download", external_url = link, categories = categoriesList, }; int external_id = 0; var task = Task.Run(async() => { external_id = await _woo.InsertProduct(p); }); task.Wait();
It is a lot of work to fetch and save categories for both posts and products. It may save you some time to use existing libraries.