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

Nikola Nikolov nikolov.tmw at gmail.com
Wed Nov 13 15:28:30 UTC 2013


Well - it's up to the developer to figure out how to handle the displaying
of the shortcode they are creating.

What you're seeing has more OOP and template-oriented approach than what
you'd normally have. I don't know if it's better or worse, but I assume it
serves their purpose if they're using it.

For instance they might want to let other plugins or the theme to override
a specific template(or might want to do that in the future) - so having a
uniform way of handling shortcodes(via the main abstract class) can make
this easier(I assume the abstract class might take care of other things -
like registering a UI element for the shortcode for instance).
This also makes it easier for other plugins to add some extra goodness -
when you have an example template to start with(an example class that
extends the main abstract class) and a base class to take care of the extra
load - adding custom shortcodes should be a breeze.

Well - all of that is just a guess of mine on why they could've chosen that
specific path.

I believe that it's worth the time to create your own solution(or borrow
from somewhere) that would take care of everything - adding a button that
lists all available shortcodes, displaying a generator form for each
shortcode, inserting it in the editor, etc. - so when you add shortcode
"xyz" you can just tell the underlying code that this shortcode has 3
parameters(two text fields and one select field) and accepts content, it's
called "Xyz Name" and it's description is "Lorem ipsum...".
Based on that your code would add some UI element that would allow the user
to select the "Xyz Name" shortcode(probably in a pop-up) and populate all
of the fields for it(so enter something in the text fields, select
something from the drop-down and maybe enter some content in the content
textarea). The user then clicks "add shortcode" and the shortcode is
magically inserted into the editor :)

Sure it would take some time to figure out a proper structure, implement it
and make sure it works in different situations, but it would be well worth
the time - your users will most-likely love you for it(let's face it - it's
difficult to remember multiple shortcodes with all of their attributes and
what they do).

Nikola


On Wed, Nov 13, 2013 at 4:43 PM, Haluk Karamete <halukkaramete at gmail.com>wrote:

> 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
> >
> _______________________________________________
> 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