diff --git a/docs/users/sidebarswidgets.rst b/docs/users/sidebarswidgets.rst index 16f10ba18..a54d41d3d 100644 --- a/docs/users/sidebarswidgets.rst +++ b/docs/users/sidebarswidgets.rst @@ -170,15 +170,29 @@ Typically used in the Article Bottom widget area, this will display a list of ca Largo Taxonomy List ------------------- -List all of the terms in a given taxonomy with links to their archive pages. This is most commonly used to generate a list of series/projects with links to their project pages. To use this widget begin by entering in the Taxonomy field the slug of the taxonomy you want to use. For example, the slug for Categories is "category"; the slug for Tags is "post_tag"; the slug for Post Prominence is "prominence"; and the slug for Series is "series". You must enter one of these slugs for the widget to function correctly. +List all of the terms in a given taxonomy with links to their archive pages. This widget is most commonly used to generate a list of series/projects with links to their project pages. An explanation of the options: -By default the widget will pull in *all* posts in the taxonomy, which could be a very large number of posts. Use the Count field to limit the number of posts displayed. You can also limit the display to specific terms in the taxonomy. To do this you must find the term's ID by visiting the list of terms in the taxonomy (under Posts in the dashboard), then hover over or click on the term and find the tag_ID number in the URL for that term. + **Title**: This is what the widget will be named. Leave blank to have no title displayed. -For example, in this URL for the term "Bacon" the term ID is 482: + **Taxonomy**: This dropdown allows you to configure the taxonomy from which terms will be drawn. Example taxonomies are Category, Tag, Post Prominence, and Series. This option defaults to Series. - ``/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=482&post_type=post`` + **Sort order**: + - Alphabetically: Terms will be sorted in alphabetical order by their name. Terms beginning with punctuation will come after terms beginning with letters. Terms beginning with numbers will come before terms beginning with letters. + - Most Recent: Terms created more recently will appear first. Term sort order is determined by the term's ID, and newer terms always have higher ID values. -After setting the taxonomy slug, count, and optionally limiting by term ID, you choose to display thumbnails and a headline of the most recent post in the taxonomy, or display the taxonomy list as as dropdown menu. The Title of the widget defaults to Categories, but you can override this with a title of your choice. + **Count**: By default the widget will pull in 5 posts from the taxonomy. Use the Count field to increase or decrease the number of posts displayed. The minimum number of terms displayed is 1. In theory you can display all terms in a taxonomy by setting the count to the number of posts in the taxonomy, but in practice you should not set the number higher than 10. Using a large count number in conjunction with the thumbnail or headline options will negatively affect your site's performance, and may cause your server to run out of memory. + + **Exclude**: Entering a comma-separated list of term IDs will exclude those terms from displayed results. To do this, go to "Posts" in the dashboard. Under "Posts" will be a list of taxonomies. Click on the desired taxonomy entry. A list of taxonomy terms will appear. Find your term in the list, then hover over or click on the term and find the tag_ID number in the URL for that term. + + For example, in this URL for the term "Bacon" the term ID is 482: + + ``/wp-admin/edit-tags.php?action=edit&taxonomy=post_tag&tag_ID=482&post_type=post`` + + **Display as dropdown**: This option causes the term results to be displayed as a plain dropdown. No thumbnails or recent posts will be displayed. + + **Display thumbnails**: Check this option if you want to display thumbnails next to the term link. If the taxonomy is "Series" and a series landing page exists for the series term, the series landing page's featured image will be displayed if it is available. In all other cases, the featured media thumbnail image from the most-recent post in the term will be displayed. + + **Display headline**: If checked, the headline of the most-recent post in the taxonomy term will be displayed. Largo Twitter Widget -------------------- diff --git a/inc/taxonomies.php b/inc/taxonomies.php index 555420e5f..d778ef72a 100644 --- a/inc/taxonomies.php +++ b/inc/taxonomies.php @@ -30,7 +30,11 @@ function largo_is_series_landing_enabled() { * @since 1.0 */ function largo_custom_taxonomies() { - if (!taxonomy_exists('prominence')) { + + /* + * Register the "Post Prominence" taxonomy, which is used to determine where posts display + */ + if ( !taxonomy_exists('prominence') ) { register_taxonomy( 'prominence', 'post', @@ -115,7 +119,45 @@ function largo_custom_taxonomies() { do_action('largo_after_create_prominence_taxonomy', $largoProminenceTerms); + /* + * Register the "Post Types" taxonomy, used for icons. This is not enabled by default in Largo. + * + * Replaces Largo_Term_Icons::register_post_type and unregister_post_types_taxonomy() + * @since 0.5.5 + * @link https://github.com/INN/Largo/issues/1173 + */ + if ( !taxonomy_exists('post-type') ) { + $enabled = ( ! of_get_option('post_types_enabled') == 0 ); + register_taxonomy( + 'post-type', + array( 'post' ), + array( + 'label' => __( 'Post Types', 'largo' ), + 'labels' => array( + 'name' => __( 'Post Types', 'largo' ), + 'singular_name' => __( 'Post Type', 'largo' ), + 'all_items' => __( 'All Post Types', 'largo' ), + 'edit_item' => __( 'Edit Post Type', 'largo' ), + 'update_item' => __( 'Update Post Type', 'largo' ), + 'view_item' => __( 'View Post Type', 'largo' ), + 'add_new_item' => __( 'Add New Post Type', 'largo' ), + 'new_item_name' => __( 'New Post Type Name', 'largo' ), + 'search_items' => __( 'Search Post Type'), + ), + 'public' => $enabled, + 'show_admin_column' => $enabled, + 'show_in_nav_menus' => $enabled, + 'hierarchical' => true, + ) + ); + } + + /** + * Register the "Series" taxonomy, used to group posts together by ongoing coverage. This is not enabled by default in Largo. + * + */ if ( ! taxonomy_exists( 'series' ) ) { + $series_enabled = largo_is_series_enabled(); register_taxonomy( 'series', 'post', @@ -135,6 +177,9 @@ function largo_custom_taxonomies() { 'new_item_name' => __( 'New Series Name' ), 'menu_name' => __( 'Series' ), ), + 'public' => $series_enabled, + 'show_admin_column' => $series_enabled, + 'show_in_nav_menus' => $series_enabled, 'query_var' => true, 'rewrite' => true, ) @@ -443,29 +488,3 @@ function largo_first_headline_in_post_array($array) { return $headline; } - -/** - * If the option in Advanced Options is unchecked, unregister the "Series" taxonomy - * - * @uses largo_is_series_enabled - * @since 0.4 - */ -function unregister_series_taxonomy() { - if ( !largo_is_series_enabled() ) { - register_taxonomy( 'series', array(), array('show_in_nav_menus' => false) ); - } -} -add_action( 'init', 'unregister_series_taxonomy', 999 ); - -/** - * If the option in Advanced Options is unchecked, unregister the "Post Types" taxonomy - * - * @uses of_get_option - * @since 0.4 - */ -function unregister_post_types_taxonomy() { - if ( of_get_option('post_types_enabled') == 0 ) { - register_taxonomy( 'post-type', array(), array('show_in_nav_menus' => false) ); - } -} -add_action( 'init', 'unregister_post_types_taxonomy', 999 ); diff --git a/inc/term-icons.php b/inc/term-icons.php index c0b8202eb..c4f6f2a94 100644 --- a/inc/term-icons.php +++ b/inc/term-icons.php @@ -22,31 +22,6 @@ function __construct() { add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts') ); add_action( 'edit_terms', array( $this, 'edit_terms' ) ); add_action( 'create_term', array( $this, 'edit_terms' ) ); - add_action( 'init', array( $this, 'register_taxonomy' ) ); - } - - - /** - * Register the taxonomy post-type - */ - function register_taxonomy() { - register_taxonomy( 'post-type', array( 'post' ), array( - 'label' => __( 'Post Types', 'largo' ), - 'labels' => array( - 'name' => __( 'Post Types', 'largo' ), - 'singular_name' => __( 'Post Type', 'largo' ), - 'all_items' => __( 'All Post Types', 'largo' ), - 'edit_item' => __( 'Edit Post Type', 'largo' ), - 'update_item' => __( 'Update Post Type', 'largo' ), - 'view_item' => __( 'View Post Type', 'largo' ), - 'add_new_item' => __( 'Add New Post Type', 'largo' ), - 'new_item_name' => __( 'New Post Type Name', 'largo' ), - 'search_items' => __( 'Search Post Type'), - ), - 'public' => true, - 'show_admin_column' => true, - 'hierarchical' => true, - ) ); } /** diff --git a/inc/widgets/largo-taxonomy-list.php b/inc/widgets/largo-taxonomy-list.php index e4cf01828..ce1445cff 100644 --- a/inc/widgets/largo-taxonomy-list.php +++ b/inc/widgets/largo-taxonomy-list.php @@ -1,21 +1,35 @@ element of terms, or 2) a customizable UL of terms. */ class largo_taxonomy_list_widget extends WP_Widget { + /** + * Constructor + */ function __construct() { $widget_ops = array( 'classname' => 'largo-taxonomy-list', - 'description' => __('List all of the terms in a custom taxonomy with links', 'largo') + 'description' => __( 'List all (or some) of the terms in a given taxonomy. Optionally with links to recent stories in each term.', 'largo' ) ); parent::__construct( 'largo-taxonomy-list-widget', __('Largo Taxonomy List', 'largo'), $widget_ops); } + /** + * Output the widget + * + * @param array $args Sidebar-related args + * @param array $instance Instance-specific widget arguments + * @link https://developer.wordpress.org/reference/functions/get_terms/ + * @uses largo_taxonomy_list_widget::render_series_list + * @uses largo_taxonomy_list_widget::render_term_list + */ function widget( $args, $instance ) { extract( $args ); - $title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Categories', 'largo' ) : $instance['title'], $instance, $this->id_base); + $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Series', 'largo' ) : $instance['title'], $instance, $this->id_base ); $is_dropdown = ! empty( $instance['dropdown'] ) ? '1' : '0'; /* @@ -25,23 +39,43 @@ function widget( $args, $instance ) { if ( $title ) echo $before_title . $title . $after_title; - /* - * The widget - */ - $cat_args = array( - 'orderby' => 'name', + // Set us up the term args + $term_args = array( 'taxonomy' => $instance['taxonomy'], 'number' => $instance['count'], - 'include' => $instance['include'], + 'exclude' => $instance['exclude'], + ); + switch ( $instance['sort'] ) { + case 'name_asc': + $term_args['orderby'] = 'name'; + $term_args['order'] = 'ASC'; + break; + default: + $term_args['orderby'] = 'id'; + $term_args['order'] = 'DESC'; + break; + } + + $defaults = array( + 'taxonomy' => 'series', + 'number' => 5, + 'exclude' => null, + 'orderby' => 'id', + 'order' => 'DESC' ); + $term_args = wp_parse_args( $term_args, $defaults ); + /* + * The dropdown option + */ if ( $is_dropdown ) { - $cats = get_categories($cat_args); ?> + $term_args['orderby'] = 'name'; + $terms = get_categories( $term_args ); ?> @@ -53,24 +87,19 @@ function widget( $args, $instance ) { }); - '; - $cat_args['title_li'] = ''; - $tax_items = get_categories($cat_args); - - switch ($instance['taxonomy']) { - case 'series': - $this->render_series_list($tax_items, $instance); - break; - case 'category': - $this->render_cat_list($tax_items, $instance); - break; - case 'post_tag': - $this->render_tag_list($tax_items, $instance); - break; - default: - $this->render_term_list($tax_items, $instance); + $tax_items = get_categories($term_args); + + if ( $instance['taxonomy'] === 'series' ) { + $this->render_series_list( $tax_items, $instance ); + } else { + $this->render_term_list( $tax_items, $instance ); } echo ''; @@ -92,13 +121,13 @@ function widget( $args, $instance ) { * @private * @since 0.5.3 */ - private function render_li($item, $thumbnail = '', $headline = '') { + private function render_li( $item, $thumbnail = '', $headline = '' ) { echo sprintf( '
  • %s
    %s
    %s
  • ', $item->taxonomy, $item->term_id, ( $thumbnail != '' ) ? "has-thumbnail" : "no-thumbnail" , - get_term_link($item), + get_term_link( $item ), $thumbnail, // the image for the series $item->cat_name, $headline @@ -112,14 +141,15 @@ private function render_li($item, $thumbnail = '', $headline = '') { * @uses largo_taxonomy_list_widget::render_li * @uses largo_featured_thumbnail_in_post_array * @uses largo_first_headline_in_post_array + * @since 0.5.3 */ private function render_series_list($tax_items, $instance) { - foreach ($tax_items as $item) { + foreach ( $tax_items as $item ) { $thumbnail = ''; $headline = ''; $posts = array(); - if ($instance['thumbnails'] == '1' || $instance['use_headline'] == '1') { + if ( $instance['thumbnails'] == '1' || $instance['use_headline'] == '1' ) { $query_args = array( 'tax_query' => array( array( @@ -129,87 +159,27 @@ private function render_series_list($tax_items, $instance) { ), ), ); - $posts = get_posts($query_args); + $posts = get_posts( $query_args ); } - if ($instance['thumbnails'] == '1' && largo_is_series_landing_enabled() ) { - $landing_array = largo_get_series_landing_page_by_series($item); + if ( $instance['thumbnails'] == '1' && largo_is_series_landing_enabled() ) { + $landing_array = largo_get_series_landing_page_by_series( $item ); // Thumbnail shall be the one for the landing page post - foreach ($landing_array as $post) { - $thumbnail = get_the_post_thumbnail($post->ID); + foreach ( $landing_array as $post ) { + $thumbnail = get_the_post_thumbnail( $post->ID ); } } - if ($thumbnail == '') { - $thumbnail = largo_featured_thumbnail_in_post_array($posts); + if ( $thumbnail == '' ) { + $thumbnail = largo_featured_thumbnail_in_post_array( $posts ); } - if ($instance['use_headline'] == '1') { - $headline = largo_first_headline_in_post_array($posts); + if ( $instance['use_headline'] == '1' ) { + $headline = largo_first_headline_in_post_array( $posts ); } - $this->render_li($item, $thumbnail, $headline); - } - } - - /** - * Find the first thumbnailed post in the category and create an
  • - * - * @private - * @uses largo_taxonomy_list_widget::render_li - * @uses largo_featured_thumbnail_in_post_array - * @uses largo_first_headline_in_post_array - */ - private function render_cat_list($tax_items, $instance) { - foreach ($tax_items as $item) { - $headline = ''; - $thumbnail = ''; - $posts = array(); - - // Only get posts if we're going to use them. - if ($instance['thumbnails'] == '1' || $instance['use_headline'] == '1') { - $posts = get_posts(array( - 'category_name' => $item->name, - )); - } - if ($instance['thumbnails'] == '1') { - $thumbnail = largo_featured_thumbnail_in_post_array($posts); - } - if ($instance['use_headline'] == '1') { - $headline = largo_first_headline_in_post_array($posts); - } - $this->render_li($item, $thumbnail, $headline); - } - } - - /** - * For a tag, find the first thumbnailed post and create an
  • - * - * @private - * @uses largo_taxonomy_list_widget::render_li - * @uses largo_featured_thumbnail_in_post_array - * @uses largo_first_headline_in_post_array - */ - private function render_tag_list($tax_items, $instance) { - foreach ($tax_items as $item) { - $headline = ''; - $thumbnail = ''; - $posts = array(); - - // Only get posts if we're going to use them. - if ($instance['thumbnails'] == '1' || $instance['use_headline'] == '1') { - $posts = get_posts(array( - 'tag' => $item->slug, - )); - } - if ($instance['thumbnails'] == '1') { - $thumbnail = largo_featured_thumbnail_in_post_array($posts); - } - if ($instance['use_headline'] == '1') { - $headline = largo_first_headline_in_post_array($posts); - } - $this->render_li($item, $thumbnail, $headline); + $this->render_li( $item, $thumbnail, $headline ); } } @@ -220,15 +190,16 @@ private function render_tag_list($tax_items, $instance) { * @uses largo_taxonomy_list_widget::render_li * @uses largo_featured_thumbnail_in_post_array * @uses largo_first_headline_in_post_array + * @since 0.5.3 */ - private function render_term_list($tax_items, $instance) { - foreach ($tax_items as $item) { + private function render_term_list( $tax_items, $instance ) { + foreach ( $tax_items as $item ) { $thumbnail = ''; $headline = ''; $posts = array(); // Only get posts if we're going to use them. - if ($instance['thumbnails'] == '1' || $instance['use_headline'] == '1') { + if ( $instance['thumbnails'] == '1' || $instance['use_headline'] == '1' ) { $query_args = array( 'tax_query' => array( array( @@ -240,76 +211,132 @@ private function render_term_list($tax_items, $instance) { ); $posts = get_posts($query_args); } - if ($instance['thumbnails'] == '1') { - $thumbnail = largo_featured_thumbnail_in_post_array($posts); + if ( $instance['thumbnails'] == '1' ) { + $thumbnail = largo_featured_thumbnail_in_post_array( $posts ); } - if ($instance['use_headline'] == '1') { - $headline = largo_first_headline_in_post_array($posts); + if ( $instance['use_headline'] == '1' ) { + $headline = largo_first_headline_in_post_array( $posts ); } - $this->render_li($item, $thumbnail, $headline); + $this->render_li( $item, $thumbnail, $headline ); } } + /** + * Sanitize and save widget arguments + */ function update( $new_instance, $old_instance ) { $instance = $old_instance; - $instance['title'] = sanitize_text_field($new_instance['title']); - $instance['taxonomy'] = strtolower(strip_tags($new_instance['taxonomy'])); - $instance['count'] = sanitize_text_field($new_instance['count']); - if ($instance['count'] == '' ) { - $instance['count'] = ''; - } else if ($instance['count'] < 1) { + $instance['title'] = sanitize_text_field( $new_instance['title'] ); + $instance['taxonomy'] = isset( $new_instance['taxonomy'] ) ? strtolower( strip_tags( $new_instance['taxonomy'] ) ) : 'series'; + $instance['sort'] = isset( $new_instance['sort'] ) ? strtolower( strip_tags( $new_instance['sort'] ) ) : 'id_desc'; + $instance['count'] = sanitize_text_field( $new_instance['count'] ); + + // Default is 5 as of 0.5.5, not infinite + if ( $instance['count'] == '' ) { + $instance['count'] = 5; + } else if ( $instance['count'] < 1 ) { $instance['count'] = 1; } - $instance['include'] = sanitize_text_field($new_instance['include']); - $instance['dropdown'] = !empty($new_instance['dropdown']) ? 1 : 0; - $instance['thumbnails'] = !empty($new_instance['thumbnails']) ? 1 : 0; - $instance['use_headline'] = !empty($new_instance['use_headline']) ? 1 : 0; + $instance['dropdown'] = !empty( $new_instance['dropdown'] ) ? 1 : 0; + $instance['thumbnails'] = !empty( $new_instance['thumbnails'] ) ? 1 : 0; + $instance['use_headline'] = !empty( $new_instance['use_headline'] ) ? 1 : 0; + $instance['exclude'] = sanitize_text_field( $new_instance['exclude'] ); return $instance; } + /** + * Render the widget form + */ function form( $instance ) { //Defaults $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'taxonomy' => '' ) ); $title = esc_attr( $instance['title'] ); - $taxonomy = esc_attr( $instance['taxonomy'] ); - $count = $instance['count']; - $include = $instance['include']; + $count = isset( $instance['count'] ) ? esc_attr( $instance['count'] ) : 5; + $sort = esc_attr( $instance['sort'] ); + $instance['taxonomy'] = isset( $instance['taxonomy'] ) ? $instance['taxonomy'] : 'series'; $dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false; $thumbnails = isset( $instance['thumbnails'] ) ? (bool) $instance['thumbnails'] : false; $use_headline = isset( $instance['use_headline'] ) ? (bool) $instance['use_headline'] : false; + $exclude = $instance['exclude']; + + // Create ', + $order, + selected( $instance['sort'], $order, false ), + $label + ); + } ?> -

    -

    - - - . + + +

    + +

    + +

    - - + +

    - - + + +

    + +

    + + +

    -

    /> - +

    + /> + +
    +

    -

    /> - +

    + /> +

    -

    /> - +

    + /> +