YOOtheme Pro is here! The best WordPress and Joomla theme. Learn more

Avatar a.scott.mcculloch asked

Widgetkit not pulling pages from custom content types

I'm using CustomPress from WPMU primarily to create additional page organization, and also have categories enabled for those pages -- they are basically just like the regular WP "Pages". Unfortunately, Widgetkit doesn't "see" those pages.

On this thread: https://yootheme.com/support/question/75142
it is suggested that one might make a custom widget content plugin... so, that's what I'd like to do, but I don't know quite how.

I think I just need to make a copy of /wp-content/plugins/widgetkit/plugins/content/wordpress and then edit the plugin.php file. The problem is that I'm not at all sure what to change in plugin.php to get it to look for the custom content pages.

What in this file would need to be edited to see those pages?

        <?php  
        $config = array(  

        'name' => 'content/wordpress',  

        'main' => 'YOOtheme\\Widgetkit\\Content\\Type',  

        'config' => array(  

            'name'  => 'wordpress',  
            'label' => 'WordPress',  
            'icon'  => 'plugins/content/wordpress/content.svg',  
            'item'  => array('title', 'content', 'media', 'link'),  
            'data'  => array(  
                'number'   => 5,  
                'content'  => 'intro',  
                'category' => array(),  
                'order_by' => 'post_date',  
                'author'   => 'author',  
                'date'     => 'publish_up',  
                'categories' => 'categories'  
            )  

        ),  

        'items' => function($items, $content, $app) {  

            $order = explode('_asc', $content['order_by']);  
            $args  = array(  
                'numberposts' => $content['number'] ?: 5,  
                'category'    => $content['category'] ? implode(',', $content['category']) : 0,  
                'orderby'     => isset($order[0]) ? $order[0] : 'post_date',  
                'order'       => isset($order[1]) ? 'ASC' : 'DESC',  
                'post_status' => 'publish'  
            );  

            foreach (get_posts($args) as $post) {  

                $data = array();  

                $data['title']      = get_the_title($post->ID);  
                $data['link']       = get_permalink($post->ID);  
                $data['author']     = $content['author'] ? get_the_author_meta('display_name', $post->post_author) : '';  
                $data['date']       = $content['date'] ? $post->post_date : '';  

                $pieces = get_extended($post->post_content);  

                if ($content['content'] == 'excerpt') {  
                    $data['content'] = $app['filter']->apply($post->post_excerpt, 'content');  
                } else if ($content['content'] == 'intro') {  
                    $data['content'] = $app['filter']->apply($pieces['main'], 'content');  
                } else {  
                    $data['content'] = $app['filter']->apply($pieces['main'].$pieces['extended'], 'content');  
                }  

                if ($content['categories']) {  

                    $data['categories'] = array();  

                    foreach(wp_get_post_categories($post->ID) as $catid) {  
                        $cat = get_category($catid);  
                        $data['categories'][$cat->name] = esc_url( get_category_link($cat->term_id) );  
                    }  

                }  

                if ($thumbnail = get_post_thumbnail_id($post->ID)) {  
                    $image = wp_get_attachment_image_src($thumbnail, 'full');  
                    $data['media'] = $image[0];  
                }  

                $data['tags'] = array();  

                if ($tags = get_the_tags($post->ID)) {  
                    foreach($tags as $tag) {  
                        $data['tags'][] = $tag->name;  
                    }  
                }  

                // map custom fields  
                foreach ((array)$content['mapping'] as $map) {  
                    if (isset($map['name']) && isset($map['field'])) {  
                        $value = get_post_meta($post->ID, $map['field']);  
                        $data[$map['name']] = array_shift($value);  
                    }  
                }  

                $items->add($data);  
            }  

        },  

        'events' => array(  

            'init.admin' => function($event, $app) {  
                $app['scripts']->add('widgetkit-wordpress-controller', 'plugins/content/wordpress/assets/controller.js');  
                $app['angular']->addTemplate('wordpress.edit', 'plugins/content/wordpress/views/edit.php');  
            }  

        )  

    );  

    return defined('WPINC') ? $config : false;  

Thanks,
Scott

  • WordPress
  • Widgetkit

Edited

10 Answers

1

Avatar a.scott.mcculloch answered

I've come back to this now... it turned out we didn't need it then, but we do now...

So, what I've found is that the code I posted above works in terms of pulling pages from the custom post type. And in the Widgetkit settings it dynamically pulls the possibilities from the custom taxonomy. However, when displaying the Widget on the site, it's not filtering the entries by the taxonomy, only by the custom content type. So, I think I'm missing something.

My guess is that I need something like this:

                if ($content['categories']) {  

                $data['categories'] = array();  

                foreach(wp_get_post_categories($post->ID) as $catid) {  
                    $cat = get_category($catid);  
                    $data['categories'][$cat->name] = esc_url( get_category_link($cat->term_id) );  
                }  

            }  

for the taxonomies (and I realize I could be off-track there).

Here's what I've got currently in plugin.php (slightly different than above, as I'm streamlining to only deal with a single custom taxonomy)

    <?php  

$config = array(  

    'name' => 'content/custompress',  

    'main' => 'YOOtheme\\Widgetkit\\Content\\Type',  

    'config' => array(  

        'name'  => 'custompress',  
        'label' => 'CustomPress Learning Materials',  
        'icon'  => 'plugins/content/custompress/content.svg',  
        'item'  => array('title', 'content', 'media', 'link'),  
        'data'  => array(  
            'number'   => 5,  
            'content'  => 'intro',  
            'category' => array(),  
            'order_by' => 'post_date',  
            'author'   => 'author',  
            'date'     => 'publish_up',  
            'post_type' => array(),  
            'tax_query' => array(),  
            'categories' => 'categories'  
        )  

    ),  

    'items' => function($items, $content, $app) {  

        $order = explode('_asc', $content['order_by']);  
        $args  = array(  
            'post_type' => $content['post_type'],  
            'tax_query' => array(  
                    'taxonomy' => 'presentation',  
                    'field' => 'slug',  
                    'terms' => $content['presentation'],  
                ),  
            'numberposts' => $content['number'] ?: 5,  
            //'category'    => $content['category'],  
            'orderby'     => isset($order[0]) ? $order[0] : 'post_date',  
            'order'       => isset($order[1]) ? 'ASC' : 'DESC',  
            'post_status' => 'publish'  
        );  

        foreach (get_posts($args) as $post) {  

            $data = array();  

            $data['title']      = get_the_title($post->ID);  
            $data['link']       = get_permalink($post->ID);  
            $data['author']     = $content['author'] ? get_the_author_meta('display_name', $post->post_author) : '';  
            $data['date']       = $content['date'] ? $post->post_date : '';  

            $pieces = get_extended($post->post_content);  

            if ($content['content'] == 'excerpt') {  
                $data['content'] = $app['filter']->apply($post->post_excerpt, 'content');  
            } else if ($content['content'] == 'intro') {  
                $data['content'] = $app['filter']->apply($pieces['main'], 'content');  
            } else {  
                $data['content'] = $app['filter']->apply($pieces['main'].$pieces['extended'], 'content');  
            }  

            if ($content['categories']) {  

                $data['categories'] = array();  

                foreach(wp_get_post_categories($post->ID) as $catid) {  
                    $cat = get_category($catid);  
                    $data['categories'][$cat->name] = esc_url( get_category_link($cat->term_id) );  
                }  

            }  

            if ($thumbnail = get_post_thumbnail_id($post->ID)) {  
                $image = wp_get_attachment_image_src($thumbnail, 'full');  
                $data['media'] = $image[0];  
            }  

            $data['tags'] = array();  

            if ($tags = get_the_tags($post->ID)) {  
                foreach($tags as $tag) {  
                    $data['tags'][] = $tag->name;  
                }  
            }  

            // map custom fields  
            foreach ((array)$content['mapping'] as $map) {  
                if (isset($map['name']) && isset($map['field'])) {  
                    $value = get_post_meta($post->ID, $map['field']);  
                    $data[$map['name']] = array_shift($value);  
                }  
            }  

            $items->add($data);  
        }  

    },  

    'events' => array(  

        'init.admin' => function($event, $app) {  
            $app['scripts']->add('widgetkit-custompress-controller', 'plugins/content/custompress/assets/controller.js');  
            $app['angular']->addTemplate('custompress.edit', 'plugins/content/custompress/views/edit.php');  
        }  

    )  

);  

return defined('WPINC') ? $config : false;  

...and here's edit.php

    <?php  

    global $wpdb;  

    $fields =  $wpdb->get_col($wpdb->prepare("SELECT DISTINCT meta_key FROM {$wpdb->postmeta} WHERE meta_key NOT LIKE %s ORDER BY meta_key", $wpdb->esc_like( '_' ).'%'));  

?>  

<div class="uk-form uk-form-horizontal" ng-class="vm.name == 'contentCtrl' ? 'uk-width-large-2-3 wk-width-xlarge-1-2' : ''" ng-controller="custompressCtrl as wp">  

    <h3 class="wk-form-heading">{{'Content' | trans}}</h3>  
    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-post_type">{{'Post Type' | trans}}</label>  
        <div class="uk-form-controls">  
            <select id="wk-post_type" class="uk-form-width-large" ng-model="content.data['post_type']" multiple>  
                <?php foreach (get_post_types() as $post_type) : ?>  
                    <option value="<?php echo $post_type; ?>"><?php echo $post_type; ?></option>  
                <?php endforeach; ?>  
            </select>  
        </div>  
    </div>  
    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-learning-materials">{{'Presentation' | trans}}</label>  
        <div class="uk-form-controls">  
            <select id="wk-learning-materials" class="uk-form-width-large" ng-model="content.data['material']" multiple>  
                <?php foreach (get_terms('presentation', $args = '') as $presentation) : ?>  
                    <option value="<?php echo $presentation->slug; ?>"><?php echo $presentation->name; ?></option>  
                <?php endforeach; ?>  
            </select>  
        </div>  
    </div>  

    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-number">{{'Limit' | trans}}</label>  
        <div class="uk-form-controls">  
            <input id="wk-number" class="uk-form-width-large" type="number" value="5" min="1" step="1" ng-model="content.data['number']">  
        </div>  
    </div>  

    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-order">{{'Order' | trans}}</label>  
        <div class="uk-form-controls">  
            <select id="wk-order" class="uk-form-width-large" ng-model="content.data['order_by']">  
                <option value="post_none">{{'Default' | trans}}</option>  
                <option value="post_date">{{'Latest First' | trans}}</option>  
                <option value="post_date_asc">{{'Latest Last' | trans}}</option>  
                <option value="post_modified">{{'Modified First' | trans}}</option>  
                <option value="post_modified_asc">{{'Modified Last' | trans}}</option>  
                <option value="post_title">{{'Alphabetical' | trans}}</option>  
                <option value="post_title_asc">{{'Alphabetical Reversed' | trans}}</option>  
                <option value="post_author">{{'Author' | trans}}</option>  
                <option value="post_author_asc">{{'Author Reversed' | trans}}</option>  
                <option value="rand">{{'Random' | trans}}</option>  
            </select>  
        </div>  
    </div>  

    <h3 class="wk-form-heading uk-margin-large-top">{{'Mapping' | trans}}</h3>  

    <div class="uk-form-row">  
        <span class="uk-form-label">{{'Fields' | trans}}</span>  
        <div class="uk-form-controls">  

            <div class="uk-grid uk-grid-small uk-grid-width-1-2">  
                <div>  
                    <input class="uk-width-1-1" type="text" value="content" disabled>  
                </div>  
                <div>  
                    <select class="uk-width-1-1" ng-model="content.data['content']">  
                        <option value="intro">{{'Intro Text' | trans}}</option>  
                        <option value="full">{{'Full Text' | trans}}</option>  
                        <option value="excerpt">{{'Excerpt' | trans}}</option>  
                    </select>  
                </div>  
            </div>  

            <div class="uk-grid uk-grid-small uk-grid-width-1-2">  
                <div>  
                    <input class="uk-width-1-1" type="text" value="date" disabled>  
                </div>  
                <div>  
                    <select class="uk-width-1-1" ng-model="content.data['date']">  
                        <option value="">{{'None' | trans}}</option>  
                        <option value="publish_up">{{'Publish Up' | trans}}</option>  
                    </select>  
                </div>  
            </div>  

            <div class="uk-grid uk-grid-small uk-grid-width-1-2">  
                <div>  
                    <input class="uk-width-1-1" type="text" value="author" disabled>  
                </div>  
                <div>  
                    <select class="uk-width-1-1" ng-model="content.data['author']">  
                        <option value="">{{'None' | trans}}</option>  
                        <option value="author">{{'Author' | trans}}</option>  
                    </select>  
                </div>  
            </div>  

            <div class="uk-grid uk-grid-small uk-grid-width-1-2">  
                <div>  
                    <input class="uk-width-1-1" type="text" value="categories" disabled>  
                </div>  
                <div>  
                    <select class="uk-width-1-1" ng-model="content.data['categories']">  
                        <option value="">{{'None' | trans}}</option>  
                        <option value="categories">{{'Categories' | trans}}</option>  
                    </select>  
                </div>  
            </div>  

            <div class="uk-grid uk-grid-small uk-grid-width-1-2" ng-repeat="map in wp.mapping">  
                <div>  
                    <input class="uk-width-1-1" type="text" ng-model="map.name" placeholder="{{'Field name' | trans}}">  
                </div>  
                <div class="uk-flex uk-flex-middle">  
                    <select class="uk-width-1-1" ng-model="map.field">  
                        <?php foreach ($fields as $field) : ?>  
                        <option value="<?php echo $field; ?>"><?php echo $field; ?></option>  
                        <?php endforeach; ?>  
                    </select>  
                    <a class="uk-margin-left uk-text-danger" ng-click="wp.deleteMap(map)"><i class="uk-icon-trash-o"></i></a>  
                </div>  
            </div>  

            <p>  
                <a class="uk-button" ng-click="wp.addMap()">{{'Add' | trans}}</a>  
            </p>  

        </div>  
    </div>  

</div>  

What have I missed?

Right now, when I set the post type and presentation in the Widgetkit settings, it ends up including all entries in the post type instead of just those that match the selected taxonomy.

Thanks,
Scott

Edited

1

Avatar pamolade answered

Hi a.scott.mcculloch

Did you ever find a solution for this?
I really need a custom content providor with a custom taxonomy

0

Avatar a.scott.mcculloch answered

I received a suggestion elsewhere that perhaps adding a line for post_type in the args would work:

$args  = array(  
'post_type'   => array( 'post' , 'learning_materials', 'page', 'self_assessments', 'coach_pages') ,  
'numberposts' => $content['number'] ?: 5,  
'category'    => $content['category'] ? implode(',', $content['category']) : 0,  
'orderby'     => isset($order[0]) ? $order[0] : 'post_date',  
'order'       => isset($order[1]) ? 'ASC' : 'DESC',  
'post_status' => 'publish'  
);  

That didn't work. :(
I even tried removing 'post' and 'page' just to see what would happen... widgetkit still pulled only regular wp posts/pages, which leads me to wonder if the post_type arg is just ignored?

Any other ideas I could try?

Edited

0

Avatar a.scott.mcculloch answered

I'm still trying to figure out how to get Widgetkit to detect and pull from custom content types... not really getting anywhere.

I've posted the question over at the support for the custom content type plugin I'm using - they gave the suggestion above that didn't work. They weren't able to come up with anything else to try.

I can't be the only one who uses custom content types and Widgetkit and would like them to work together! Or maybe I am?

0

Avatar matthijs Support answered

I m sure you are on the right track. I do not have any experience with Wordpress code, but the content provider is where you will need to be. If you can retrieve the custom fields there somehow, that is where you can link them to the widget.

I can't really help with the Wordpress part, but if you have questions on how to attach it to Widgetkit, feel free to ask.

0

Avatar a.scott.mcculloch answered

I figured it out... sort of...

It turns out (for some reason I don't fully understand) when using Wordpress as the content provider, Widgetkit doesn't seem to be able to find by category and post_type at the same time. If I remove category, then post_type works, otherwise as long as category is one of the $args then it will only get post and page post_types.

So, the next step was to use fully custom taxonomy rather than the built in categories. Unfortunately, my skills aren't enough to quickly figure out how to make it all dynamic (i.e., I have to hard-code in some of my taxonomy related stuff)... but I will only have a few taxonomies in this case, so that works for me... for now. (One other drawback is that I'm not sure what I'd need to do to be able to set more than one "term" for a taxonomy - probably needs a foreach loop, I think).

Anyway, what I ended up with is this (only showing the portions where I made changes or additions):

edit.php

<div class="uk-form-controls">  
            <select id="wk-post_type" class="uk-form-width-large" ng-model="content.data['post_type']" multiple>  
                <?php foreach (get_post_types() as $post_type) : ?>  
                    <option value="<?php echo $post_type; ?>"><?php echo $post_type; ?></option>  
                <?php endforeach; ?>  
            </select>  
        </div>  
    </div>  
    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-program">{{'Programs' | trans}}</label>  
        <div class="uk-form-controls">  
            <select id="wk-programs" class="uk-form-width-large" ng-model="content.data['programs']" multiple>  
                <?php foreach (get_terms('programs', $args = '') as $program) : ?>  
                    <option value="<?php echo $program->slug; ?>"><?php echo $program->name; ?></option>  
                <?php endforeach; ?>  
            </select>  
        </div>  
    </div>  
    <div class="uk-form-row">  
        <label class="uk-form-label" for="wk-learning-materials">{{'Learning Materials' | trans}}</label>  
        <div class="uk-form-controls">  
            <select id="wk-learning-materials" class="uk-form-width-large" ng-model="content.data['material']" multiple>  
                <?php foreach (get_terms('learning_material_type', $args = '') as $materials) : ?>  
                    <option value="<?php echo $materials->slug; ?>"><?php echo $materials->name; ?></option>  
                <?php endforeach; ?>  
            </select>  
        </div>  
    </div>  

And plugin.php

    'items' => function($items, $content, $app) {  

        $order = explode('_asc', $content['order_by']);  
        $args  = array(  
            'post_type' => $content['post_type'],  
            'tax_query' => array(  
                'relation' => "OR",  
                array(  
                    'taxonomy' => 'programs',  
                    'field' => 'slug',  
                    'terms' => $content['programs'],  
                ),  
                array(  
                    'taxonomy' => 'learning_material_type',  
                    'field' => 'slug',  
                    'terms' => $content['material'],  
                ),  
            ),  
            'numberposts' => $content['number'] ?: 5,  
            //'category'    => $content['category'],  
            'orderby'     => isset($order[0]) ? $order[0] : 'post_date',  
            'order'       => isset($order[1]) ? 'ASC' : 'DESC',  
            'post_status' => 'publish'  
        );  

I'm also considering adding the ability to select the AND/OR for the "relation" in the tax query array... not sure if I'll need it, but who knows.

If, after seeing this, anyone has ideas on how to make it better, I'm open to suggestions. :-)

0

Avatar matthijs Support answered

Thanks for your feedback. Programmers should think of a way you could encapsulate your data and methods, so you could better predict what a method will do. Ow wait, that is Object Oriented Programming, the rest of the world already does that :)
I'm sorry, I really can't stand these vague global functions like the_post() from which you'll never know what it returns.

You see that making things work for your case is easier than trying to make it work for any case, preferably with some settings and mappings.
I hope this helps fellow WP users.

0

Avatar a.scott.mcculloch answered

Yes, and since I'm not a programmer, I don't really know my Object from my ---, so I don't know what the difference would be.

For my skill level, dealing with the specifics of my current needs is definitely easier than trying to come up with a more complete solution -- the downside is that now I will have to edit the plugin every time we add a new taxonomy. :(

Anyway, this works for now.

0

Avatar a.scott.mcculloch answered

Hi pamolade

Sadly, no. I have yet to get this working properly. I asked on WP developer I know, but he hasn't done much with custom taxonomies so couldn't do much off the top of his head and didn't have time to dig into it. :(

0

Avatar stefano.ulivieri answered

It would be a very useful feature...it's sad that we can't use this options

thanks anyway a.scott.mcculloch

Know someone who can answer? Share a link to this question via email or twitter.