[wp-hackers] Is there a way to get the callback function name out of a shortcode _programmatically_?

Haluk Karamete halukkaramete at gmail.com
Wed Nov 13 14:43:46 UTC 2013


It does work but only for simple "string" cases such as caption or gallery.

What I mean by simple "string case" is the following ones.
  'embed' => string '__return_false' (length=14)
  'wp_caption' => string 'img_caption_shortcode' (length=21)
  'caption' => string 'img_caption_shortcode' (length=21)
  'gallery' => string 'gallery_shortcode' (length=17)
  'audio' => string 'wp_audio_shortcode' (length=18)
  'video' => string 'wp_video_shortcode' (length=18)

the moment, the string becomes an array. the code stops working.

like this...
  'vc_column_inner' =>

Visual composer is a remarkable tool but the way it handles its shortcode
is different.
At the end of the day, to tell you the truth, their stuff only looks like a
shortcode but deep down in the engine, it could be anything.

I xdebugged thru the whole thing to find out and it turned out that the
visual composer was eventually running the_widget wordpress function for
that shortcode...  ( I pasted the section below for those who are
interested in seeing). But, I'm totally confused in the way they implement
their ( what seems to be) shortcodes.

I always thought that to make a shortcode such as [myshortcode], you follow
a few simple steps such as
add_shortcode('myshortcode','myshortcode_handler') and then you add your
handler function as function myshortcode_handler($atts,$content = null) and
then off you go...

well, with visual composer, i got a "welcome to the hell" situation. :(

I'm trying to get to the bottom of how the information flow from the
shortcode all the way where it ends up as widget.. And the first step for
that is to get to the FIRST FUNCTION that it runs as soon  WP detects a
visual composer shortcode.

And from the global shortcode_tags array, I'm unable to get to it..

I'm very sorry if this sounds like too specific.

Thanks

...
basically, what I see as [vc_wp_posts show_date="1" title="wp title"
number="4" el_class=""]
 in my post editor, ends up running this code

<?php
$output = $title = $number = $show_date = $el_class = '';
extract( shortcode_atts( array(
    'title' => __('Recent Posts'),
    'number' => 5,
    'show_date' => false,
    'el_class' => ''
), $atts ) );
$atts['show_date'] = $show_date;

$el_class = $this->getExtraClass($el_class);

$output = '<div class="vc_wp_posts wpb_content_element'.$el_class.'">';
$type = 'WP_Widget_Recent_Posts';
$args = array();

ob_start();
the_widget( $type, $atts, $args );
$output .= ob_get_clean();

$output .= '</div>' . $this->endBlockComment('vc_wp_posts') . "\n";

echo $output;


which is isolated in vc_wp_posts.php file which gets pulled in from their
class implementation which is in a nut shell goes like this;

/**
 * WPBakery Visual Composer Shortcodes main
 *
 * @package WPBakeryVisualComposer
 *
 */

/*
This is were shortcodes for default content elements are
defined. Each element should have shortcode for frontend
display (on a website).

This will add shortcode that will be used in frontend site
*/

define('VC_SHORTCODE_CUSTOMIZE_PREFIX', 'vc_theme_');
define('VC_SHORTCODE_BEFORE_CUSTOMIZE_PREFIX', 'vc_theme_before_');
define('VC_SHORTCODE_AFTER_CUSTOMIZE_PREFIX', 'vc_theme_after_');
define('VC_SHORTCODE_CUSTOM_CSS_FILTER_TAG', 'vc_shortcodes_css_class');
if (!class_exists('WPBakeryShortCode')) {
    abstract class WPBakeryShortCode extends WPBakeryVisualComposerAbstract
{

        protected $shortcode;
        protected $html_template;

        protected $atts, $settings;


some more blah blah... and then... we get to a section that includes the
vc_wp_posts.php file

        protected function loadTemplate( $atts, $content = null) {
            $output = '';
            if(!$this->html_template) $this->findShortcodeTemplate();
            if($this->html_template) {
                ob_start();
                include ($this->html_template);    // <----- THIS IS WHERE
vc_wp_posts.php GETS PULLED IN.
                $output = ob_get_contents();
                ob_end_clean();
            } else {
                trigger_error(sprintf(__('Wrong template for `%s` shortcode
in class `%s`. Please check your mapping settings for this code. Error',
'js_composer'), $this->shortcode, get_class($this)));
            }

            return $output;
        }

The main puzzle to me, what does this have to do with the basic shortcode
implementation that we all are familiar with.  which looks like this at the
post editor ( [vc_wp_posts show_date="1" title="wp title" number="4"
el_class=""]
 ) and you end up going thru the class implementation I summed up above...
Why this complexity?
Is this a great hack into the shortcode system or is it just a commonly
used traditional technique that I need to learn about.

Thanks..


On Nov 12, 2013 10:53 PM, "Nikola Nikolov" <nikolov.tmw at gmail.com> wrote:

> Hm... I wonder if the code I wrote doesn't work. Can you try to get the
> callback for gallery? And see if that works.
>
>
> On Wed, Nov 13, 2013 at 1:37 AM, Haluk Karamete <halukkaramete at gmail.com
> >wrote:
>
> > Sorry guys to bother you back on this.... In a slightly more complicated
> > case ( a visual composer shortcode ) where the shortcode data is stored
> in
> > an object in the $shortcode_tags array, I'm hitting a brick wall.
> >
> > The shortcode I'm after is "vc_wp_posts" and I use this one liner to
> > ATTEMPT to get it   $callback = get_shortcode_callback("vc_wp_posts");
> >
> > using the function we had yesterday.
> >
> > function get_shortcode_callback( $shortcode ) {
> >     return isset( $GLOBALS['shortcode_tags'][ $shortcode ] ) ?
> > $GLOBALS['shortcode_tags'][ $shortcode ] : false;
> > }
> >
> > and it comes back with a FALSE.
> >
> > I know why but I don't know how to get to piece I need to...
> >
> > Here is the $shortcode_tags var dump view
> >
> > shortened for brewity
> >
> > array (size=74)
> >   'embed' => string '__return_false' (length=14)
> >   'wp_caption' => string 'img_caption_shortcode' (length=21)
> >   'caption' => string 'img_caption_shortcode' (length=21)
> >   'gallery' => string 'gallery_shortcode' (length=17)
> >   'audio' => string 'wp_audio_shortcode' (length=18)
> >   'video' => string 'wp_video_shortcode' (length=18)
> >   'vc_column_inner' =>
> >     array (size=2)
> >       0 =>
> >         object(WPBakeryShortCode_VC_Column_Inner)[173]
> >           protected 'predefined_atts' =>
> >             array (size=3)
> >               ...
> >           protected 'shortcode' => string 'vc_column_inner' (length=15)
> >           protected 'html_template' => null
> >           protected 'atts' => null
> >           protected 'settings' =>
> >             array (size=11)
> >               ...
> >           protected 'is_plugin' => boolean true
> >           protected 'is_theme' => boolean false
> >       1 => string 'output' (length=6)
> >   'vc_row' =>
> >     array (size=2)
> >       0 =>
> >         object(WPBakeryShortCode_VC_Row)[174]
> >
> > etc...
> >
> > now I am gonna fast forward to the section that deals with the shortcode
> > I'm after...
> >
> > and here it is...
> >
> > 'vc_wp_posts' =>
> >     array (size=2)
> >       0 =>
> >         object(WPBakeryShortCode_VC_Wp_Posts)[118]
> >           protected 'shortcode' => string 'vc_wp_posts' (length=11)
> >  <------------ this is where the information we are after.
> >           protected 'html_template' => null
> >           protected 'atts' => null
> >           protected 'settings' =>
> >             array (size=6)
> >               ...
> >           protected 'is_plugin' => boolean true
> >           protected 'is_theme' => boolean false
> >       1 => string 'output' (length=6)
> >
> >   'vc_wp_links' =>
> >     array (size=2)
> >       0 =>
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Tue, Nov 12, 2013 at 5:28 AM, J.D. Grimes <jdg at codesymphony.co>
> wrote:
> >
> > > Yeah, I thought it would reduce bootstrap. Using do_shortcode() is so
> > easy
> > > for new devs to do, if we want them to use the better alternative, I
> > think
> > > it would be adopted quicker in a wrapper like this.
> > >
> > > On Nov 11, 2013, at 10:02 PM, Ryan McCue <lists at rotorised.com> wrote:
> > >
> > > > J.D. Grimes wrote:
> > > >> Here is a function that does just that:
> > > >
> > > > This seems like something we should bring in to core to avoid
> everyone
> > > > using `do_shortcode` and running the full regex parser every time.
> > > >
> > > > I see you proposed http://core.trac.wordpress.org/ticket/25435 but
> it
> > > > got wontfix'd. Anyone else think we should reopen?
> > > >
> > > > --
> > > > Ryan McCue
> > > > <http://ryanmccue.info/>
> > > > _______________________________________________
> > > > wp-hackers mailing list
> > > > wp-hackers at lists.automattic.com
> > > > http://lists.automattic.com/mailman/listinfo/wp-hackers
> > >
> > > _______________________________________________
> > > wp-hackers mailing list
> > > wp-hackers at lists.automattic.com
> > > http://lists.automattic.com/mailman/listinfo/wp-hackers
> > >
> > _______________________________________________
> > wp-hackers mailing list
> > wp-hackers at lists.automattic.com
> > http://lists.automattic.com/mailman/listinfo/wp-hackers
> >
> _______________________________________________
> wp-hackers mailing list
> wp-hackers at lists.automattic.com
> http://lists.automattic.com/mailman/listinfo/wp-hackers
>


More information about the wp-hackers mailing list