wp-theatre
wp-theatre copied to clipboard
Rethink the data model
I haven't finished my research (https://github.com/slimndap/wp-theatre/issues/317) on the current implementation yet, but would like to start the discussion on this anyway.
I think we should prepare a data model that follows known best-practices and is close to core, which means in the big picture we use post_types for singular data and taxonomies to group these data. By doing so we can make use of the endless built-in features like performant queries, caching, contextual pagination, backend UI, blocks, etc., that WordPress already provides. So when we follow for example ...
-
There are many use cases that can be modified to avoid performance problems. [...] use a custom taxonomy and a term [...] in order to leverage the indexes. Meta queries · WordPress VIP Documentation
-
A taxonomy is a tool that lets us group or classify posts. Post meta lets us store unique information about specific posts. 10up Engineering Best Practices
1. we should register two new taxonomies.
- a shadow-taxonomy, shadowing the existing productions post_type, registered for (aka selectable from) the existing events post_type
- a utility-taxonomy to group events and or productions by any kind of semantic, but static, data like "On sale", "Sold Out", "Cancelled" or "Hidden"
2. register production & event post_type only if needed
All this should be kept most generic, portable and site-agnostic as it could. By that I mean, we should register the necessary post_types only if there aren't already post_types in place that could or should be used instead. When we only provide the meaningful, semantic connection between those post_types without having to worry about every aspect of e.g. a good venue and event management tool, we can focus on the code with real theatre context.
Introducing filterable post_type slugs for productions and events would be the way to go, I think. So people can use, from the numerous plugins available, whatever they want to manage their events or productions. We only register the bare-bone post_types with some minimal additions, if no other plugins are running and providing what is needed.
This is great.
The crux of the current data model's challenge is the ordering mechanism for productions and events. Both entities utilize the _wpt_order
meta-field for order in queries. This value, formatted as Ymd
, depends on:
- The event's start date for events
- The start date of the nearest upcoming event for productions
This meta-field's purpose is two-fold:
- Ensure correct display sequence for productions and events
- Facilitate date-range selections (e.g., upcoming or for a specific month)
The production value is recalibrated hourly via WP-Cron, given that the nearest event may change as time progresses. Additionally, any save operation on an event or production triggers this recalibration. Such frequent recalibrations are computationally intensive and are complicated by the opaque nature of background processing.
In search of performance improvements, I considered the menu_order
field within the wp_posts
table to utilize WordPress's native post ordering. But, unexpectedly, this field isn't indexed, making its efficiency gain uncertain.
I like the concept of the shadow taxonomy. I am not sure about the utility taxonomy. I can not think of an actual use case for this. Eg. so far, nobody has ever wanted to group events by ticket status. Perhaps grouping by venue?
All this should be kept most generic, portable and site-agnostic as it could. By that I mean, we should register the necessary post_types only if there aren't already post_types in place that could or should be used instead. When we only provide the meaningful, semantic connection between those post_types without having to worry about every aspect of e.g. a good venue and event management tool, we can focus on the code with real theatre context.
Let's see if I understand correctly. We register two post types: productions and events and provide the infrastructure to link the two (using events-tax) and to retrieve productions and events in the right order. We also provide the interface to manage them in the WordPress admin.
Developers can optionally specify existing post types using filters, in which case we do not register our own post type. We use the existing post types instead.
Do we still provide basic functionality to add information about venues, prices, ticket status? Maybe make it possible to deactivate this using filters as well? And how this this work with the HTML output or with the Gutenberg blocks?
This is great.
Cool you like the idea. Thank you.
The crux of the current data model's challenge is the ordering mechanism for productions and events. Both entities utilize the
_wpt_order
meta-field for order in queries. This value, formatted asYmd
, depends on:
- The event's start date for events
- The start date of the nearest upcoming event for productions
This meta-field's purpose is two-fold:
- Ensure correct display sequence for productions and events
- Facilitate date-range selections (e.g., upcoming or for a specific month)
This sounds indeed like one of the most important and tricky aspects to refactor. I opened #322 to collect event-related information.
The production value is recalibrated hourly via WP-Cron, given that the nearest event may change as time progresses. Additionally, any save operation on an event or production triggers this recalibration. Such frequent recalibrations are computationally intensive and are complicated by the opaque nature of background processing.
Let‘s see how much of these jobs are still needed after we refactored the event data. Basically I think it is a good idea to go with WordPress‘ default way, the WP-Cron, like you did. Bigger setups will have some background-job processing in place, what should also be based on registered WP-Cron jobs, but should be out of our scope.
In search of performance improvements, I considered the
menu_order
field within thewp_posts
table to utilize WordPress's native post ordering. But, unexpectedly, this field isn't indexed, making its efficiency gain uncertain.
Unsure what to do about this.
The only gain from using the existing menu_order
column is that WordPress will automatically show events in the correct order, without altering WP_Query.
I like the concept of the shadow taxonomy.
Me too. As I came across this kind of implementation the first time, it really hitted me hard as it is so nice, simple and super-close to core.
I am not sure about the utility taxonomy. I can not think of an actual use case for this. Eg. so far, nobody has ever wanted to group events by ticket status. Perhaps grouping by venue?
Having an additional taxonomy for some of the existing post_meta data makes sense (to me) when you are able to group some posts by this exact same post_meta data. From my understanding post_meta should only be used when it is meant to save unique post-data that does not fit into the existing post_content field by its meaning or semantic. I will start collecting the real use-cases from the existing code at #317
Let's see if I understand correctly. We register two post types: productions and events and provide the infrastructure to link the two (using events-tax)
Yes, we register two post_types: production & event Also we register a taxonomy: production-shadow This will give us all of the necessary infrastructure to link the two (using production-shadow tax), no need for us to provide any additional UI.
and to retrieve productions and events in the right order. We also provide the interface to manage them in the WordPress admin.
I’m unsure about this because it seems to be the more difficult aspect, which we will have to discuss and decide, on how to handle the event-data at all.
#322
Developers can optionally specify existing post types using filters, in which case we do not register our own post type. We use the existing post types instead.
Yes. 100%
Do we still provide basic functionality to add information about venues, prices, ticket status? Maybe make it possible to deactivate this using filters as well? And how this this work with the HTML output or with the Gutenberg blocks?
This paragraph could be several new issues also, but for now I would say, that all of what you mentioned should be part of separate extensions. I can imagine different scenarios where the one or the other might be needed or even not.
This will give us all of the necessary infrastructure to link the two (using production-shadow tax), no need for us to provide any additional UI.
We need some UI in the admin to let the user see all events that are tied to a production. Also, there needs to be a way to create a new event for a production. I don't think we should let the user mess around with the default taxonomy meta box.
We need some UI in the admin to let the user see all events that are tied to a production.
We will have the default sorting & filtering within the wp_theatre_event
admin-table via clicking on assigned tags, categories or even production(shadow)s, which in the future could look like this: wp-admin/edit.php?post_type=wp_theatre_event&wp_theatre_prod_shadow=hamlet
Also, there needs to be a way to create a new event for a production.
Yes, you are right.
I can think of an extra Button, a Command Palette command or an enhanced default taxonomy meta box.
I don't think we should let the user mess around with the default taxonomy meta box.
Let it be a good starting point, ok?
To better understand the necessary steps to go, I wrote down this first draft of a migration-roadmap for the production-event-relations. Maybe we can create some more helpful tracking issue out of it.
Current data modell (version 0.18.3)
taxonomy :arrow_right:post_type :arrow_down: |
post_tag |
category |
---|---|---|
wp_theatre_prod |
:heavy_check_mark: | :heavy_check_mark: |
wp_theatre_event |
:knot: | :knot: |
wp_theatre_season |
:heavy_minus_sign: | :heavy_minus_sign: |
Proposed NEW data modell (maybe version 1.0.0)
taxonomy :arrow_right:post_type :arrow_down: |
post_tag |
category |
NEW wp_theatre_prod_shadow |
---|---|---|---|
wp_theatre_prod |
:heavy_check_mark: | :heavy_check_mark: | :arrows_clockwise: |
wp_theatre_event |
:knot: | :knot: | :heavy_check_mark: |
wp_theatre_season |
:heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: |
1. New dependencies & needed preparation :exclamation:
- Find a way to include|reference|require and run third-party dependencies without violating the WordPress.org Plugin Guidelines
- Register a NEW
wp_theatre_prod_shadow
taxonomy, for example based on the arguments over here: https://github.com/figuren-theater/deprecated__Figuren_Theater__v2/blob/21c39010aebe616b9bf77c4a3341b82bce77188b/mu-plugins/Figuren_Theater/src/Network/Taxonomies/Taxonomy__ft_production_shadow.php#L127-L196 - Create a relationship between post_type and taxonomy using
\Shadow_Taxonomy\Core\create_relationship( 'wp_theatre_prod', 'wp_theatre_prod_shadow' );
-
or by re-using some of this:
- https://github.com/figuren-theater/deprecated__Figuren_Theater__v2/blob/21c39010aebe616b9bf77c4a3341b82bce77188b/mu-plugins/Figuren_Theater/src/Network/Taxonomies/TAX_Shadow.php#L121-L240
2. Changes to the existing codebase
- Refactor ~~how~~ when Events inherit taxonomy-terms from its related Productions (#324 )
- Rewrite all custom queries within shortcodes etc. to:
- Deprecate admin-UI elements which were needed to handle the
post_meta
data - Deprecate the use of the
post_meta
keys, maybe using_doing_it_wrong()
, because there is no deprecate_post_meta() function I know of. - Rewrite unittests
3. Upgrade routines needed
Is there any version-checking-upgrade-or-migrate-data function in place, I haven't found? Otherwise we'd need something like this to have our migration run only once per site.
3.1. for existing Productions
- Loop over all public
wp_theatre_prod
posts- Create a shadow-taxonomy term for each
3.2. for existing Events
- Loop over
wp_theatre_event
-posts withwp_theatre_prod
post_meta- Get the shadowed taxonomy term from the production specified in the queried
wp_theatre_prod
post_meta field -
wp_set_object_terms()
-
delete_post_meta_by_key
( 'wp_theatre_prod' )
- Get the shadowed taxonomy term from the production specified in the queried
All this could also be done for Seasons, but I suggest separating all seasons-related code into an extension.
Find a way to include|reference|require and run third-party dependencies without violating the WordPress.org Plugin Guidelines
We are mainly interested in the concept of shadow taxonomies. Not necessarily the code, which is not that complex. I already played with the concept a few months ago: https://github.com/slimndap/theater-feature-generic-posttypes. Note that the code uses different CPT names (Events and Dates) in stead of productions and events. I think I also opted to make the code less generic/abstract, to make it easier to understand.
I did some more tests and I think the shadow taxonomy plugin fails if two events have the exact same name. This is because the current code bases the title of the shadow term on the title of the parent post: https://github.com/mrbobbybryant/shadow-taxonomy/blob/master/includes/shadow-taxonomy.php#L96
I did some more tests and I think the shadow taxonomy plugin fails if two events have the exact same name. This is because the current code bases the title of the shadow term on the title of the parent post: https://github.com/mrbobbybryant/shadow-taxonomy/blob/master/includes/shadow-taxonomy.php#L96
I‘m sorry for being late …. But how should it be possible within WordPress, that two posts of the same post_type
can get same slug. I would argue, that it is impossible thanks to wp_unique_post_slug()
.
As far as I understand the code, it provides the post_title AND the slug, where the latter is covered by the mentioned wp_unique_post_slug()
.
I unfortunately don’t see the problem, yet.
Nevertheless, we don’t have to rely on mrbobbybriants implementation.
In the last couple of weeks I saw two nice implementations of shadow-taxonomies in the wild. Both were covering the relation between a venue-post_type and a venue-shadow-taxonomy. Both are worth reading the code.
- GatherPress‘ class-venue.php
- Simple Location‘ venues (I‘ll provide the link as soon as….I remember)