Moqui Slug Data Model Handling

I’m currently working on a front facing eCommerce web application.

It has an idea of a slug that are related to products, categories, etc

They’re treated basically as an id that is URL Character Compatible. It also needs to be changeable (unlike primary key ids) for the purposes of changing the words associated with a data structure like a product or category. It also needs to be internationalization-compatible for different locations of the users going to the website.

They’re used for making web url pages more human readable as well as SEO friendly.

I’m wondering how the concept of a Slug should apply to the data models for products, categories, and more.

After looking at the product and category data models, and I think that there are a couple ways that would work for this:

  1. Use the pseudoId:
    Most Data Model Concepts already have a pseudoId. This wouldn’t change the data model, but would mean that the pseudoId's would need to be parsed (i.e. to remove spaces) and have additional meaning not necessarily commonly associated with a pseudoId.
  2. Add a slug field to the Data Model:
    This would change the data model, but it would be a direct relationship with obvious meaning for the data model.
  3. Something else. I’m open to ideas

Let me know what you think @marwand, @integrines, @info.integrin, and @jonesde.

@micheal i checked the moqui datamodel and it appears Product > psuedoId is defaulted to Product Id and Category > psuedoId is defaulted to productCategoryId, i’m not sure of the original intended purpose of psuedoId, however from my perspective having a separate column for slug will be cleaner even though it requires a data model change, let us hear from others as well.

1 Like

I quickly skimmed through mantle-usl to get an idea of the current usage of the pseudoId field, and it looks like create#VariantProduct uses the product’s pseudoId as a prefix for the productId of the variant product to be created.

                productId = product.pseudoId ?: product.productId
                String productName = product.productName
                for (EntityValue feature in featureList) {
                    // get the feature type Enumeration record for the description
                    EntityValue typeEnum = ec.entity.find("moqui.basic.Enumeration")
                            .condition("enumId", feature.productFeatureTypeEnumId).useCache(true).one()
                    productId = productId + "_" + (feature.abbrev ?: feature.productFeatureId)
                    productName = productName + " " + feature.description
                }

That being said, I think we should extend the Product entity with a slug field to prevent conflicts that might arise from this, or any other implementation-specific usage of the field within the community.

1 Like

The pseudoId field on various entities, including Product and ProductCategory, is meant to be the internal SKU # used by a company. If a company doesn’t have numeric IDs for things like a UPC barcode then they might use text, and longer text even for the internal ID in the Product.pseudoId field.

For a slug ‘ID’ we could perhaps generate it from the product name (generally the ProductContent with the Product Name type, defaulting to Product.productName), or do that if a slug value is not specified… in a place where it has its own home… and the best place for that is using the ProductIdentification entity.

ProductIdentification is designed for one record per ID type and ProductOtherIdentification allows multiple IDs per type and split by other factors such as productStoreId. For that reason I’m thinking ProductOtherIdentification might be better, allow for a different value for different stores.

Either way what we need is a new ProductIdentificationType like:

<moqui.basic.Enumeration description=“URL Slug” enumId=“PidtUrlSlug” enumTypeId=“ProductIdentificationType”/>

Does that seem like a workable solution?

2 Likes

Thanks for the clarification about the data model.

I think that this one of those would be a good solution. I’m just not sure which one. Is there a use case for a slug that would be used across different stores or another reason?

The downside of using ProductOtherIdentification is that it adds complexity.

I just looked at both entities and ProductOtherIdentification is clearly the one to use. It may add complexity, but it also adds flexibility to how products and productstores are structured.

Although what do you think @marwand and @integrines?

What David suggested is definitely more complex, but looking at it from a Unified Data Model point of view, it makes sense to use the ProductOtherIdentification entity since slug is a form of ID, and it technically is a direct function of ProductStore.

When generating the ProductOtherIdentification slug, we can keep productStoreId as null so that it applies to all stores by default.

1 Like

is there a reason Slug Url needs to be specific to a Product Store ever, i tend to think using ProductIdentfication will be slightly less complex to implement than ProductOtherIdentification [which is for a product store], if we agree Slug Url is not specific to a Product Store, should we use ProductIdentification, or am i missing a point here.

1 Like

Yeah. I’ve worked on projects where essentially the same product is used across stores, but each store wants to be very specific about what their product needs to look like and what the product is.

For example, if one store is selling a white label product branded for their store A and the same white label product is sold for store B, but they target different audiences, then it would make sense to change the slug to something each store wants. I’m also sure that there are better examples. The ideas is that it’s feasible to need that functionality, so might as well plan ahead for it.

It certainly does add some complexity, however the implementation of one vs another is basically the same.

Sounds good, using ProductOtherIndentification and keeping null as productStoreId will work to apply slug to all stores by default and it gives the flexibility to add product specific slugs as needed.

1 Like

How would you approach a Slug URL for a ProductCategory? There is no ProductCategoryOtherIdentification entity.

That’s a good question… the ProductCategory model is not built out nearly as much as the main Product entities. We could add a ProductCategoryIdentification entity, or I suppose we could use a ProductCategoryContent record for that but then it’s different and ugly in a way… so maybe best to add a new entity (called “ProductCategoryIdent” so it doesn’t go over 30 chars with 2 underscores added, similar to the newer ProductOtherIdentification entity).

1 Like

Sounds good. I’ll check that out.