Make WordPress Core

Opened 10 years ago

Closed 10 years ago

Last modified 8 years ago

#30302 closed feature request (maybelater)

Network sites taxonomy

Reported by: aurovrata's profile aurovrata Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.0
Component: Networks and Sites Keywords: close
Focuses: multisite Cc:

Description

If we consider sites to be equivalent to posts in a Network Dashboard, then we can imagine introducing taxonomy to group these sites together.

This has the advantage to be able to identify grammatically which site belong together, which are parent & child sites, and therefore allow for easy cross linking of sites that belong together in a given portal. It opens the door to many possibilities such as common theme for a group.

Change History (6)

#1 @jeremyfelt
10 years ago

  • Keywords close added

Hi @aurovrata, thanks opening a ticket! I think this is an excellent idea as a plugin. I'm not sure that we're ready for taxonomy to be applied to objects other than posts at this point. I can imagine a configuration where sites are mirrored with posts on the primary network's main site—I actually did this once and it was strangely satisfying. :)

Currently, if you stretch a bit, sites can be grouped together in multiple networks. This doesn't necessarily achieve everything that you're looking for, but could be a start.

For big proposed features such as this, we're using a features as plugins process. You may want to write up the idea in more detail and see what support there is. The best part about creating a feature plugin is that it is still available for use even if it is not included in core.

#2 @aurovrata
10 years ago

Hi @jeremyfelt, thanks for the positive reply. Will definitely try the plugin route. In fact as suggested by @ipstenu in the forums, am going to fork a defunct plugin which attempted something along these lines.

#3 @johnbillion
10 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from new to closed

I like this idea too. Let's see how the plugin pans out.

#4 follow-up: @Biont
8 years ago

Hello everyone.

I am currently developing such a plugin and I from my experience with it, I do not think it can be done in a satisfying way without touching the core.

The ideal solution would be create all 4 taxonomy tables into the network scope (by using a "site_" prefix or something) and then treat Sites (and possibly Users) as just another object_type.

This almost works. However, the current state of the Taxonomy API hampers this in several ways:

  • Table names are hardcoded to use a single site context
  • Caching is hardcoded to use a single site context

The only way to get it working is to wrap most calls to the Taxonomy API with code that edits the "$wpdb->term_*" tables, and disables/invalidates all caching that might take place.

The alternative would be to copy&paste most of the API to use different cache keys and tables.

So neither of these options is actually feasible. I took the "smoke and mirrors"-approach of modifying global state, because it lets me use the existing API and is somewhat future-proof, but I am not happy at all with it.

What I am getting at: I do not think that waiting for a feature plugin is going to help much. It will not a good solution.

It would be rather simple to pull of if a few changes could be made:

  • Make WP_Taxonomy and WP_Term network aware. So when registering a taxonomy, you could pass a "network"=>true argument and thus register a taxonomy in network scope.
  • Make WP_Term_Query, WP_Tax_Query, etc. aware of network taxonomies and terms. (This will probably extend to some utility functions as well, see below) Make them use different tables and cache keys depending on the context.

One pitfall is the global $wp_taxonomies and the issue of name collisions. There might be a network "category" as well as a blog "category". As soon as custom taxonomies come in, taxonomy_exists(), get_taxonomy() etc. will need be distinguish between contexts and the intention of the call will probably need to be clear as well (eg. by passing a "network" parameter). Alternatively, we could introduce network_taxonomy_*() functions. Those would draw from a different pool of taxonomies and would setup queries to use a different context.

I would love to hear some input on this. I'm aware that this may not be the most-requested feature, but for large networks, this would be critical functionality. How can we proceed?

#5 in reply to: ↑ 4 ; follow-up: @aurovrata
8 years ago

@Biont interesting inputs

I am currently developing such a plugin and I from my experience with it, I do not think it can be done in a satisfying way without touching the core.

what's your approach? I had initially started on this project but never got to the point of releasing a plugin in the repo.... just not enough time.

I had experimented in creating a hidden cpt in the main site, and creating 1 post for each child site along with a custom taxonomy to associate each post/site with a network-wide taxonomy.

I had started to integrate the taxonomy in network dashboard using a custom page and wanted to expose the cpt/taxonomy core functions through a set of custom functions.

A lot of work.

#6 in reply to: ↑ 5 @Biont
8 years ago

Replying to aurovrata:

what's your approach? I had initially started on this project but never got to the point of releasing a plugin in the repo.... just not enough time.

Many of the following details are already scattered throughout my previous post, but I'll condense it down.

I wanted to actually extend the Taxonomy API so that Sites can be used as object types. The API is flexible enough to do that, but it does not have any multisite concept at all.

So I created all 4 term_* tables with a network prefix and then tried to wire it up to the existing API. This gave me a lot of trouble, as all table names and cache keys are hardcoded.

When working with a network taxonomy, you have to do most of it via my plugin API, which wraps the existing Taxonomy API. To give you an idea, have a look at this code:

<?php
class API{
 public function insert_network_term(){

   $this->setup_env(); // Set up table names. Disable caching. Replace entry in $wp_taxonomies
   wp_insert_term();
   $this->breakdown_env();

 }
}

This works, but is hacky and will likely yield bugs. Caching is currently giving me most problems because I cannot really prevent WP from caching, or inject my own parameters

Still, I am seeing good results so far.

I then proceeded to add the Network UI. Most of the existing templates are too hardcoded as well, so I registered my own pages and added views that make use of my wrapper API. I also handle saving myself.

Querying sites by taxonomy can then be done by filtering "sites_clauses" and passing back join & where clauses. The SQL for that can be fetched with a regular Tax_Query as long as you wrap it:

<?php
class NetworkTaxQuery extends \WP_Tax_Query {

        /**
         * @var API
         */
        private $api;

        /**
         * NetworkTaxQuery constructor.
         *
         * @param array             $args
         * @param API               $api
         */
        public function __construct( $args, API $api ) {

                parent::__construct( $args );
                $this->api        = $api;
        }

        public function get_sql( $primary_table, $primary_id_column ) {
                // pass  $wpdb->blogs, 'blog_id' into this method to query the sites table
                $this->api->setup_env();
                $result = parent::get_sql( $primary_table, $primary_id_column );
                $this->api->teardown_env();

                return $result;
        }
}
Last edited 8 years ago by Biont (previous) (diff)
Note: See TracTickets for help on using tickets.