¿Cómo ordenar categorías en WordPress?

8 minutos de lectura

avatar de usuario
Saneef

yo suelo wp_list_categories() para obtener la lista de todas las categorías y generar la barra de navegación. ¿Hay alguna manera de ordenar estas categorías en un orden particular que no sea el orden alfabético?

por ejemplo: Conectar, Noticias y vistas, Preguntas y respuestas, Hola Startup, Startup 101…

La mayoría de los temas no usan la descripción de la categoría para nada. La solución fácil que hice fue usar números en la descripción. La publicación principal aquí actualmente tiene un truco de jQuery desde aquí, no es necesario.

Supongo que también puede agregar campos de pedido personalizados.

Sólo

$categories = get_categories( array(
    'orderby' => 'description',
    'order'   => 'ASC'
) );

  • Esta es la mejor respuesta en mi opinión.

    – Mo Alsaedi

    20 de febrero de 2019 a las 17:06

  • ¡Esta es una solución tan inteligente! Mucho menos dolor de cabeza que las otras soluciones.

    – zen_1991

    24 de julio de 2019 a las 12:13

  • ¿Qué pasa con las categorías de publicaciones personalizadas?

    – Narén Verma

    20 de enero a las 7:34

Enfoque técnico

El problema en wordpress core es que la tabla wp_terms no tiene term_order columna. Eso significa que wordpress estándar no admite el orden de términos personalizado. si miras esto Estructura de la base de datos de WP puedes encontrar la mesa wp_term_relationships. Esta tabla es responsable de las relaciones entre las publicaciones y la taxonomía (sus categorías) Y esta tabla tiene un term_order columna.

Ahora, con una simple instrucción SQL ALTER TABLE wp_terms ADD term_order INT(11) NOT NULL DEFAULT 0 (no olvides el $wpdb->wp_terms variable) puede agregar una columna a la tabla, que es responsable de su orden de categoría personalizado. Luego puede poner su orden de categoría personalizado en estas dos columnas de wp_term_relationships y wp_terms. Cuando todo esté terminado, puede conectarse al filtro de get_terms_args y cambiar el orderby a term_order.

Aquí una lista de todos los enlaces relevantes para el enfoque técnico:

Un plugin puede hacer el trabajo por ti

Verifique mi complemento para resolver esto: Gestión de categorías reales de WordPress. WP RCM crea un campo adicional term_order en la tabla de términos de wp. También trae muchas otras características útiles, como puede ver en la captura de pantalla a continuación. Te permite organizar tus categorías de wordpress de una manera agradable. Es fácil de usar, solo arrastrar y soltar sus categorías y moverlo a un orden específico. El plugin funciona en todos Tipos de publicaciones personalizadas.

Orden de categorías de arrastrar y soltar

De la descripción del producto que puedo citar. Si quieres probar el complemento, también hay un demostración en la página del complemento.

Hay muchos complementos gratuitos.

Esto se puede resolver con muchos complementos gratuitos disponibles en el repositorio de complementos de wordpress.org. Simplemente busque “orden de categoría” en su Tablero de WordPress> Complementos> Instalar.

avatar de usuario
Ezhil

Esto está incorporado wordpress_wp_list_categories

wp_list_categories('orderby=name');

Creo que eso te ayudaría.

avatar de usuario
aitor

Lo hice generando varias listas de términos. Lo llamo luego por mi propio orden. Soy un principiante de PHP.

Primero, almaceno, en una variable diferente, la identificación para cada término de categoría:

$terms = get_terms('my_taxonomy', 'hide_empty=0');
        foreach ( $terms as $term ) {
           ${$term->slug} = get_term_by('slug', $term->slug, 'product_cat');
           ${$term->slug.'_array'} = (array)${$term->slug};
           ${$term->slug.'_array_id'} =${$term->slug.'_array'}['term_id'];
      };

Luego, creo varios argumentos para cada wp_list_categories() excluyendo, con esta variable los términos que quiero:

      $args = array(
        'taxonomy'     => 'my_taxonomy',
        'orderby'      => 'name',
        'show_count'   => true,
        'pad_counts'   => false,
        'hierarchical' => true,
        'title_li'     => '',
        'hide_empty'   => 0,
        'show_option_all' => 'Show all',
        'exclude'    => array( $term1_array_id, $term2_array_id )
      );

      $args_1 = array(
        'taxonomy'     => 'my_taxonomy',
        'orderby'      => 'name',
        'show_count'   => true,
        'pad_counts'   => false,
        'hierarchical' => true,
        'title_li'     => '',
        'hide_empty'   => 0,
        'exclude'    => array( $term3_array_id, $term4_array_id, $term1_array_id )
      );

      $args_2 = array(
        'taxonomy'     => 'my_taxonomy',
        'orderby'      => 'name',
        'show_count'   => true,
        'pad_counts'   => false,
        'hierarchical' => true,
        'title_li'     => '',
        'hide_empty'   => 0,
        'exclude'    => array( $term1_array_id, $term4_array_id, $term5_array_id )
      );

Finalmente, puedo llamar por separado cada lista de términos:

<ul>
    <?php wp_list_categories( $args ); ?>
    <?php wp_list_categories( $args_1 ); ?>
    <?php wp_list_categories( $args_2 ); ?>
</ul>

Use el complemento gratuito Orden de categoría y Términos de taxonomía Ordenar

No encontré nada, así que construí mi propio método. Lo abstraje en una clase abstracta para mi complemento, de ahí el código adicional, pero puede extraer los métodos.

El método principal para mirar es format_hierarchy()

// The parent class
abstract class Taxonomy {
    protected bool $_terms_loaded;
    
    protected array $terms;
    protected array $formatted_terms;
    
    public function __get( $property ) {
        if ( $property === 'formatted_terms' ) {
            if ( !isset( $this->formatted_terms ) ) $this->format_hierarchy();
            return $this->formatted_terms;
        }
        
        if ( substr( $property, 0, 1 ) === '_' ) die( 'Cannot get private properties' );

        if ( property_exists( $this, $property ) )
            return $this->$property;
    }

    /**
     * Formats the taxonomy's terms into a hierarchy of term_blocks and saves the value as a property to the class
     * 
     * @return              array       an array of `[term_taxonomy_id:number] => term_block` like:
     *                                      array(
     *                                          array( // parent $term_block
     *                                              'term' => WP_Term,
     *                                              'children' => array( $term_blocks… )
     *                                          ),
     *                                          …$term_blocks…
     *                                      )
     */
    public function format_hierarchy():array {
        if ( !$this->_load_terms() ) return [];

        // Holds a reference to every category, parents and children
        $term_blocks = [];

        // Holds a reference to every top most level category
        $parents = [];

        foreach ( $this->terms as $term ) {
            // Add itself to the list of all categories
            $term_block = [
                'children' => [],
                'term' => $term
            ];
            
            // Add itself to the array of all categories
            if ( !isset( $term_blocks[ $term->term_taxonomy_id ] ) )
                $term_blocks[ $term->term_taxonomy_id ] =& $term_block;
            
            // If it's a child category…
            if ( $term->parent !== 0 ) {
                // If the parent hasn't been created yet, create it
                if ( !isset( $term_blocks[ $term->parent ] ) )
                    $term_blocks[ $term->parent ] = [
                        'children' => [],
                        'term' => null
                    ];
                    
                $term_blocks[ $term->parent ][ 'children' ][] =& $term_block;
            } else
                // Otherwise it's a parent
                $parents[ $term->term_taxonomy_id ] =& $term_blocks[ $term->term_taxonomy_id ];

            // set the term block's WP_Term property
            $term_blocks[ $term->term_taxonomy_id ][ 'term' ] =& $term;
            // This is needed so that the loop doesn't readd the same reference over and over again
            unset( $term ); unset( $term_block );
        }
        
        return $this->formatted_terms = $parents;
    }

    /**
     * Given a WP_Term property value, and a property key, recursively searches through all of the terms for it
     * 
     * @property    $term_val       mixed       The property value to find
     * @property    $prop           string      The property key for the value
     * @property    $with_parent    ?boolean    Whether to return the top level parent as well
     * @property    $term_blocks    ?array      Array of term blocks
     * @return                      array       If $with_parent is true, returns an [ $found_term_block, $top_level_parent ]
     *                                          Otherwise returns only the found term block
     */
    public function find_term_by(
        $term_val,
        string $prop,
        bool $with_parent = false,
        $term_blocks = null
    ):?array {
        if ( is_null( $term_blocks ) ) $term_blocks = $this->formatted_terms;
        foreach ( $term_blocks as $term_block ) {
            if ( $term_block[ 'term' ]->{$prop} === $term_val ) return $term_block;
            if ( count( $term_block[ 'children' ] ) &&
                ( $found = $this->find_term_by( $term_val, $prop, false, $term_block[ 'children' ] ) )
            ) return $with_parent ? [ $found, $term_block ] : $found;
        }
        return null;
    }

    /**
     * Loads the taxonomy terms once from the DB
     */
    protected function _load_terms():bool {
        if ( isset( $this->_terms_loaded ) ) return $this->_terms_loaded;
        
        $this->terms = get_terms(
            array(static::$taxonomy),
            array(
                    'hide_empty'    => false,
                )
        );

        if ( !$this->terms ) {
            ClassErrorHandler::handle_exception(
                new \WP_Error( 500, 'Failed to load category terms: \'' . static::$taxonomy . '\'' )
            );
        }

        return $this->_terms_loaded = !!$this->terms;
    }
}

// The Implementation
class TaxonomyProductService extends Taxonomy {
    public static string $taxonomy;
    public static string $slug;

    /**
     * To be called upon taxonomy registration long before any instance is required
     */
    public static function define_taxonomy( string $slug, string $taxonomy ) {
        static::$slug = $slug;
        static::$taxonomy = $taxonomy;
    }
}

Inmediatamente después de registrar la taxonomía personalizada, llamo a TaxonomyProductService::define_taxonomy( ‘url-slug’, ‘product-service’ );

Y por ultimo como se usa

$tax = new TaxonomyProductService();
$terms = $tax->formatted_terms;
// search for a term whose slug === `my-term`, and return the parent category
list( $current_term, $parent_term ) = $tax->find_term_by( 'my-term', 'slug', true );

avatar de usuario
andres patton

Para el beneficio de futuros visitantes, aquí está la solución fácil a este problema:

Ahora hay una serie de complementos que le permiten ordenar categorías u otras taxonomías personalizadas en WordPress. Puedes ver algunos de ellos en el directorio de complementos de WordPress página de etiqueta “orden de categoría”. Puedo confirmar personalmente que Orden de taxonomía personalizado NE el complemento hace el trabajo.

¿Ha sido útil esta solución?