Dynamic content in a widget

I have to make a widget from where the user will be able to add a few images and then I will show only some of them, randomly, and it will be automatically changed on page refresh. The problem is that the number of images is not known, it may be 2, it may be 5. I was thinking of using an “add more” jQuery button but I have problems with working on data from an array.

Has somebody done something like this before? If you have another idea about doing this, I’d be glad to hear of it.

Read More

Note: If you have knowledge about a widget which uses this kind of function do not hesitate to tell me, maybe I can get inspiration from there.

Related posts

Leave a Reply

2 comments

  1. I have a little to none experience in developing a plugin or widgets, but I believe this is certainly doable in a custom WordPress theme.

    1. Output an ajax multiple file upload form in the sidebar. Link
    2. Handle the file uploads and save them as attachment. Link
    3. After you get the attachment(s) ID, save them as an array in the user’s meta e.g ‘sidebar_image’. Codex
    4. Back to the sidebar, check if current user already have the ‘sidebar_image’ meta.
    5. If she does have a value, then just create a attachment query, according to the meta value. Codex

    If you want this method as a widget. The function on step 2 and 3 will be the same if you use a proper ajax method.

    Hope this help.

  2. This can be solved with fairly simple elements: a Shortcode and the Text Widget.

    First, we enable the shortcode functionality for the widget:

    // Enable shortcodes in the Text Widget
    add_filter( 'widget_text', 'do_shortcode' );
    

    Useful: Shortcodes everywhere

    Then we create a shortcode that will grab images from a given post or page and display a random number of it. As we will load in random order, at each page load the images will vary.

    The usage will be [random-image id="99" total="4"]. “id” is the post/page ID. You can even leave this post in Draft state, so it doesn’t show up in the site. “total” is optional and represents the number of images to show, if there are less images attached it doesn’t matter, it’ll show all that exist.

    You can have a couple of posts for storing the images and use one widget for each. A Custom Post Type could be created and the get_posts part complexified upon it, but I’ll leave that as an exercice for the reader 😉

    Check the comments for further details:

    // Declare our shortcode
    add_shortcode( 'random-image', 'wpse_45638_random_image' );
    
    /**
     * Shortcode
     */
    function wpse_45638_random_image( $atts, $content = null )
    {   
        // ID not provided, bail out
        if( !isset( $atts['id'] ) )
            return;
    
        // Initiate variables, 
        $html = '';
        $total = isset( $atts['total'] ) ? $atts['total'] : -1;
        $gallery = wpse_45638_get_gallery( $atts['id'], $total );
    
        // No images, bail out
        if( !$gallery )
            return;
    
        // Build the thumbnails
        foreach( $gallery as $image )
        {
            $html .= '<div style="padding:10px;width:75px;float:left"><a href="'
                . $image['file'] 
                . '"><img src="'
                . $image['t_file']
                . '"  style="width:100%"></a></div> ';
        }
    
        // Return contents of the shortcode
        return $html;
    }
    
    /**
     * Get images from a post
     *
     * @param int $post_id Target post/page/cpt
     * @param int $total   Number of images to retrieve
     */ 
    function wpse_45638_get_gallery( $post_id, $total )
    {
        $args = array( 
            'post_type'     => 'attachment',
            'numberposts'   => $total,
            'post_parent'   => $post_id,
            'post_mime_type' => 'image',
            'orderby' => 'rand'
        ); 
    
        $attachments = get_posts( $args );
        $arr = array();
    
        if ($attachments) 
        {
            foreach ( $attachments as $img ) 
            {
                // Grab our data - This can be improved
                $data = wp_get_attachment_metadata( $img->ID );
                $thumb = wp_get_attachment_thumb_url( $img->ID);loga($thumb);
                $file = wp_get_attachment_url( $img->ID);loga($file);
                $arr[] = array( 
                    'width' => $data['width'],
                    'height' => $data['height'],
                    'file' => $file,
                    't_width' => $data['sizes']['thumbnail']['width'],
                    't_height' => $data['sizes']['thumbnail']['height'],
                    't_file' => $thumb,
                );
            }
            return $arr;
        }
        return false; // no images found
    }