0

UPDATE:

I have this widget that allows me to CHOOSE and SHOW the latest posts from a specific category in the sidebar. Here's the code;

add_action( 'widgets_init', 'tie_categort_posts_widget' );
function tie_categort_posts_widget() {
    register_widget( 'tie_categort_posts' );
}
class tie_categort_posts extends WP_Widget {

    function tie_categort_posts() {
        $widget_ops = array( 'classname' => 'categort-posts' );
        $control_ops = array( 'width' => 250, 'height' => 350, 'id_base' => 'categort-posts-widget' );
        $this->WP_Widget( 'categort-posts-widget',theme_name .' - Category Posts', $widget_ops, $control_ops );
    }

    function widget( $args, $instance ) {
        extract( $args );

        $title = apply_filters('widget_title', $instance['title'] );
        $no_of_posts = $instance['no_of_posts'];
        $cats_id = $instance['cats_id'];
        $thumb = $instance['thumb'];

        echo $before_widget;
            echo $before_title;
            echo $title ; ?>
        <?php echo $after_title; ?>
                <ul>
                    <?php tie_last_posts_cat($no_of_posts , $thumb , $cats_id)?>    
                </ul>
        <div class="clear"></div>
    <?php 
        echo $after_widget;
    }

    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags( $new_instance['title'] );
        $instance['no_of_posts'] = strip_tags( $new_instance['no_of_posts'] );

        $instance['cats_id'] = implode(',' , $new_instance['cats_id']  );

        $instance['thumb'] = strip_tags( $new_instance['thumb'] );
        return $instance;
    }

    function form( $instance ) {
        $defaults = array( 'title' =>__( 'Category Posts' , 'tie'), 'no_of_posts' => '5' , 'cats_id' => '1' , 'thumb' => 'true' );
        $instance = wp_parse_args( (array) $instance, $defaults );

        $categories_obj = get_categories();
        $categories = array();

        foreach ($categories_obj as $pn_cat) {
            $categories[$pn_cat->cat_ID] = $pn_cat->cat_name;
        }
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>">Title : </label>
            <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" class="widefat" type="text" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id( 'no_of_posts' ); ?>">Number of posts to show: </label>
            <input id="<?php echo $this->get_field_id( 'no_of_posts' ); ?>" name="<?php echo $this->get_field_name( 'no_of_posts' ); ?>" value="<?php echo $instance['no_of_posts']; ?>" type="text" size="3" />
        </p>
        <p>
            <?php $cats_id = explode ( ',' , $instance['cats_id'] ) ; ?>
            <label for="<?php echo $this->get_field_id( 'cats_id' ); ?>">Category : </label>
            <select multiple="multiple" id="<?php echo $this->get_field_id( 'cats_id' ); ?>[]" name="<?php echo $this->get_field_name( 'cats_id' ); ?>[]">
                <?php foreach ($categories as $key => $option) { ?>
                <option value="<?php echo $key ?>" <?php if ( in_array( $key , $cats_id ) ) { echo ' selected="selected"' ; } ?>><?php echo $option; ?></option>
                <?php } ?>
            </select>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id( 'thumb' ); ?>">Display Thumbinals : </label>
            <input id="<?php echo $this->get_field_id( 'thumb' ); ?>" name="<?php echo $this->get_field_name( 'thumb' ); ?>" value="true" <?php if( $instance['thumb'] ) echo 'checked="checked"'; ?> type="checkbox" />
        </p>

    <?php
    }
}

Any suggestions on what to edit so that I will be able to "CHOOSE and SHOW random posts from a specific TAG" instead of the latest posts from a category?

UPDATE:

Here is the accompanying code, found inside functions.php, which is used by the widget above:

function tie_last_posts_cat($numberOfPosts = 5 , $thumb = true , $cats = 1){
global $post;
$orig_post = $post;

$lastPosts = get_posts('category='.$cats.'&no_found_rows=1&suppress_filters=0&numberposts='.$numberOfPosts);
foreach($lastPosts as $post): setup_postdata($post);

Basically, here is what I'm trying to achieve:

enter image description here

I was able to turn it to a TAGS widget but I can't seem to figure out how to get the tags to show on the list. Again, help is deeply appreciated.

1
  • the code that you gave is not complete code.
    – ucon89
    Nov 14, 2014 at 3:24

3 Answers 3

1

I think your idea is really nice here, but you have a couple of serious flaws in your code.

  • Never use extract(), ever. It is extremely hard to debug and can render unexpected output. It has now been completely removed from core, except in one instance as far as I can pick up from this core trac ticket. The codex has also been updated to reflect this changes as to remove extract() from all functions (Special thanks to the guys responsible for this)

  • Your word in your class name should start with a capital letter. Check the coding standard on naming conventions

  • You are using get_categories() while you need tags. The correct function to use is get_tags()

I have cleaned up your code and corrected the above problems and also rewritten the widget to get it more inline with the Widget API

I have also worked in a custom query to call the posts. You can just change this as needed

Here is the working code. (Caveat: there might be one or two smaller issues that I have missed. It is late)

class Tagged_Posts extends WP_Widget {

    public function __construct() {
        parent::__construct(
            'widget_tagged_posts', 
            _x( 'Tagged Posts Widget', 'Tagged Posts Widget' ), 
            array( 'description' => __( 'Display a list of posts from a selected tag.' ), 
            ) 
        );
        $this->alt_option_name = 'widget_tagged_posts';

        add_action( 'save_post', array($this, 'flush_widget_cache') );
        add_action( 'deleted_post', array($this, 'flush_widget_cache') );
        add_action( 'switch_theme', array($this, 'flush_widget_cache') );
    }

    public function widget( $args, $instance ) {
        $cache = array();
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_tag_posts', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = array();
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Tagged Posts' );
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );
        $number         = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
        if ( ! $number ) {
            $number = 5;
        }
        $tags_id        = $instance['tags_id'];
        $thumbnail      = $instance['thumbnail'] ? true : false; 

        $query_args = [
            'posts_per_page'    => $number,
            'tag_id'            => $tags_id,
        ];
        $q = new WP_Query( $query_args );

        if( $q->have_posts() ) {

            echo $args['before_widget'];
            if ( $title ) {
                echo $args['before_title'] . $title . $args['after_title'];
            }               

            while( $q->have_posts() ) {
                $q->the_post(); ?>

                <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>> 

                    <header class="entry-header">
                        <?php the_title( '<h1 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h1>' ); ?>
                    </header><!-- .entry-header -->

                    <?php 
                    if ( has_post_thumbnail() && true === $thumbnail ) { ?>

                        <div class="post-thumbnail">

                            <?php the_post_thumbnail(); ?>

                        </div><!--/.post-thumbnail-->

                    <?php   
                    }   
                    ?>          

                    <div class="entry-summary">
                        <?php the_excerpt(); ?>
                    </div><!-- .entry-summary -->

                </article><!-- #post-## -->

                <?php
            }


            wp_reset_postdata();
        }
            echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_tag_posts', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $instance['number']         = (int) $new_instance['number'];
        $instance['tags_id']        = (int) $new_instance['tags_id'];
        $instance['thumbnail']      = $new_instance['thumbnail'];
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_tagged_posts']) )
            delete_option('widget_tagged_posts');

        return $instance;
    }

    public function flush_widget_cache() {
        wp_cache_delete('widget_tag_posts', 'widget');
    }

    public function form( $instance ) {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        $number     = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
        $tags_id    = isset( $instance['tags_id'] ) ? absint( $instance['tags_id'] ) : 1;
        $thumbnail  = isset( $instance['thumbnail'] ) ? $instance['thumbnail'] : false; 
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

        <p>
            <label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
            <input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" />
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('tags_id'); ?>"><?php _e( 'Tag Name:' )?></label>
            <select id="<?php echo $this->get_field_id('tags_id'); ?>" name="<?php echo $this->get_field_name('tags_id'); ?>">
                <?php 
                $this->tags = get_tags();
                foreach ( $this->tags as $tag ) {
                    $selected = ( $tag->term_id == esc_attr( $tags_id ) ) ? ' selected = "selected" ' : '';
                    $option = '<option '.$selected .'value="' . $tag->term_id;
                    $option = $option .'">';
                    $option = $option .$tag->name;
                    $option = $option .'</option>';
                    echo $option;
                }
                ?>
            </select>
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('thumbnail'); ?>"><?php _e( 'Hide post thumbnail' ); ?></label>
            <?php $checked = ( $thumbnail ) ? ' checked=\"checked\" ' : ''; ?>
            <input type="checkbox" id="<?php echo $this->get_field_id( 'thumbnail' ); ?>" name="<?php echo $this->get_field_name( 'thumbnail' ); ?>" value="true" <?php echo $checked; ?> />    
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () {
    register_widget( 'Tagged_Posts' );
});

Here is a screenshot of how it looks back end

enter image description here

EDIT

From your comments

I would like the widget you provided to get random PAGES from specific tags INSTEAD OF POSTS. My pages are tagged and I thought I would just be able to edit your code to do just that but I can't seem to figure out what to replace.

You need to change the query arguments to include the orderby and post_type parameters to get the desidered output

Change the query arguments to the following

$query_args = [
'post_type' => 'page',
'orderby' => 'rand',
'posts_per_page' => $number,
'tag_id' => $tags_id,
];
8
  • Thank you Sir Pieter! The code you provided me was perfect. If I could just ask another help... I would like the widget you provided to get random PAGES from specific tags INSTEAD OF POSTS. My pages are tagged and I thought I would just be able to edit your code to do just that but I can't seem to figure out what to replace. Thanks again for your time and help!
    – Fritz1963
    Dec 7, 2014 at 20:58
  • Glad to hear is worked out for you so far. I have update my answer with your changes. Feel free to try it. Please remember to accept my answer by clicking on the checkmark next to it if this works. :-) Dec 8, 2014 at 4:40
  • Thanks again Sir Pieter! You are very helpful. Using the new code you gave, this is now how the widget looks like on the front end; 1.bp.blogspot.com/-yDYOWOQnCik/VIWguzzUEhI/AAAAAAAAXGM/… It does pull random pages from specific tags but thumbnails are missing and the widget keeps repeating its self inside the widget. I was able to make the thumbnails appear but the "widget inside the widget" is what keeping me stumped. Could you shed some light on it, please? Again, lots of thanks!
    – Fritz1963
    Dec 8, 2014 at 13:25
  • I will look into that and perform some testing on my code. There seems to be code that is misplaced. We unfortunately (again!!!!!) have to go through a couple of no power due to load shedding (viva ESKOM) so I can only work on this when our power is back. Dec 8, 2014 at 16:09
  • Thanks Sir Pieter. I will be patiently waiting for your update.
    – Fritz1963
    Dec 8, 2014 at 20:54
0

Have a try, I din't test. On line 48 change:

$categories_obj = get_categories();

with

$categories_obj = get_tags();

And also look for the tie_last_posts_cat() function in your code, and modify it accordingly.

1
  • Thanks for the help. A busted laptop kept me from replying earlier. Could you please take a second look at my updated question? Thanks again!
    – Fritz1963
    Dec 6, 2014 at 3:27
0

First, search for the function tie_last_posts_cat**.

It's probably inside functions/theme-functions.php

Then search for

$lastPosts = get_posts('category='.$cats.'&numberposts='.$numberOfPosts);

Change it to

    $args = array(
       'orderby'    =>  'rand',
       'tax_query'  => array(
           array(
               'taxonomy' => 'post_tag',
               'field'    => 'slug',
               'terms'    => 'bob',
           ),
       ),
    );
    $lastPosts = get_posts($args);

Hope this helps. in the above code, change 'bob' to your tag.

This might also help

2
  • Haven't tried it yet but it looks like your code will get random posts from CATEGORIES. What I'm trying to do is display random posts from TAGS. Could you please take a look at my updated question? I've included the *tie_last_posts_cat function for more reference. Thanks for your time!
    – Fritz1963
    Dec 6, 2014 at 3:30
  • I I've added the new code. Please check out. I hope it helps.
    – Karun
    Dec 12, 2014 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.