Opened 11 years ago
Last modified 7 years ago
#25435 assigned feature request
Introduce alternative to do_shortcode( '[shortcode]' )
Reported by: | jdgrimes | Owned by: | rmccue |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | |
Component: | Shortcodes | Keywords: | has-patch has-unit-tests needs-refresh |
Focuses: | Cc: |
Description
There are times when we want to call a shortcode programmatically. Currently, the easiest way to do this is do_shortcode( '[shortcode]' )
. But that does lots of unnecessary work. A developer has two alternatives:
- Manually search through the source and find the function that handles the shortcode, and call it directly. The only problem is that this doesn't offer a very forward-compatible solution, especially when the shortcode is being offered by a plugin.
- Search through
$shortcode_tags
to find and call the function. That's more forward-compatible, but it kind of seems hacky.
I'd like to request that we offer a core function that does number 2 rather than each developer having to implement it themselves.
Example:
call_shortcode_func( 'shortcode', $atts, $content );
(We can change the name of the function.)
Patch forthcoming.
Attachments (6)
Change History (40)
#1
follow-up:
↓ 2
@
11 years ago
- Milestone Awaiting Review deleted
- Resolution set to invalid
- Status changed from new to closed
You can just call the shortcode's callback function directly.
So for instance, the [gallery]
shortcode callback is gallery_shortcode()
, and you can do:
echo gallery_shortcode( $attr );
#2
in reply to:
↑ 1
@
11 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
Replying to DrewAPicture:
You can just call the shortcode's callback function directly.
So for instance, the
[gallery]
shortcode callback isgallery_shortcode()
, and you can do:
echo gallery_shortcode( $attr );
Yes, I know that and mentioned it above, but it becomes a bigger issue when dealing with plugins, which may change the function name without notice. I guess maybe that's an edge case though?
My thinking was that if we make people search through the source looking for the right function to call, they'll just call do_shortcode( '[shortcode]' )
instead. If we can point them to an easy to use core function, they'll probably use it.
I think this is the best solution to the problem, but if you don't think it's a real problem, or isn't big enough to require this solution, I'll respect that.
#3
@
11 years ago
- Resolution set to wontfix
- Status changed from reopened to closed
What Drew said - some wrappers cause too much reflection, like the one you are proposing
#4
@
11 years ago
+1 in favour of reopening this.
It's certainly possible to call the callback directly if you know it, but that's not necessarily the case. Shortcodes are pretty fluid, and it's possible that a plugin could change the gallery shortcode (e.g.) to its own instead.
The current solutions are either extremely heavy (do_shortcode
) or require an obscure way to call them (do_shortcode_tag
).
I think we should add something like do_single_shortcode( 'gallery', [ 'a' => 'b' ], 'optional body content' )
.
#5
@
11 years ago
- Milestone set to Future Release
- Resolution wontfix deleted
- Status changed from closed to reopened
Reopening, because rmccue-likes.
#7
in reply to:
↑ 6
@
11 years ago
Replying to nacin:
Nested shortcodes pose a bit of a problem here.
Not sure what you mean by that. If you are using nested shortcodes, then you should be using do_shortcode()
instead of this, or calling the nested ones like this before passing the the result in as the $content
.
#9
@
11 years ago
I like this.
Nested shortcodes shouldn't be a problem -- they would just call do_shortcode()
like you do now. This just allows skipping calling do_shortcode()
when you know what the shortcode/content is, unlike a nested shortcode.
#11
@
9 years ago
- Summary changed from Intoduce function for use instead of do_shortcode( '[shortcode]' ) to Introduce alternative to do_shortcode( '[shortcode]' )
#12
@
9 years ago
+1
Since this was in "600 entries in over 270 plugins"* back in 2013 (and is almost certainly worse now) it would seem like a better way forward would be to tweak do_shortcode()
to detect the case of a single shortcode being called, and if so, run do_shortcode_tag()
directly. That avoids the overhead of scanning the entire $shortcode_tags
array without adding a new function or requiring hundreds of plugins to be updated.
I know shortcodes in general are up for a rebuild, but this seems like some very low hanging fruit that could improve performance across hundreds of plugins (especially for sites with large numbers of registered shortcodes) in the meantime.
#13
@
9 years ago
- Owner set to rmccue
- Status changed from reopened to assigned
you seemed jazzed about this
#14
follow-up:
↓ 18
@
9 years ago
Rewrote the patch. Since this is intended for internal use, it now returns a WP_Error
on invalid arguments. (If you're doing output and would rather ignore stuff, probably best to call do_shortcode
still.)
If @nickciske's suggestion sounds OK, we could probably do it, but I think it's more trouble than it's worth. It'd introduce a fair bit of complexity into do_shortcode
for an edge case that's better handled by a separate function, IMO.
Testing shows it comes out barely faster than do_shortcode
, but calling it is a fair bit nicer for internal use:
$old = do_shortcode( '[gallery columns="2" ids="19,20,21,22"]' ); $new = do_single_shortcode( 'gallery', array( 'columns' => 2, 'ids' => '19,20,21,22' ) );
(Plus, the error returns mean you can actually handle invalid codes rather than just getting back your input string.)
#16
@
9 years ago
Please see 25435.3.diff for style improvements.
Thumbs up.
#18
in reply to:
↑ 14
@
9 years ago
- Keywords commit removed
Replying to rmccue:
Testing shows it comes out barely faster than
do_shortcode
...
Running 1000 iterations of each, I found do_single_shortcode()
~10% faster, and that it consumed about 52 kb less memory. Perhaps not as big a difference as we might have thought.
#20
follow-up:
↓ 21
@
9 years ago
- Keywords commit removed
25435.4.diff fixes up the docs a little bit.
I'm not sure the WP_Error
is terribly useful without also citing the shortcode tag that doesn't have a registered callback. Can we add that to the string?
#21
in reply to:
↑ 20
@
9 years ago
Replying to DrewAPicture:
I'm not sure the
WP_Error
is terribly useful without also citing the shortcode tag that doesn't have a registered callback. Can we add that to the string?
Good thinking; added to the translated string.
Replying to jdgrimes:
Perhaps not as big a difference as we might have thought.
Indeed, although I think adding this adds a nice API for internal use, and it's a bit cleaner than formatting a string just to call a shortcode.
#22
@
9 years ago
- Keywords has-unit-tests added
25435.6.diff adds translator comments to the WP_Error
strings, as well as some tests for the new function.
#23
@
9 years ago
- Keywords needs-refresh added
do_shortcode()
and do_single_shortcode()
sound synonymous. New func needs a different name since they do totally different things.
This ticket was mentioned in Slack in #core by wonderboymusic. View the logs.
9 years ago
#26
@
8 years ago
- Milestone changed from Future Release to 4.8
Would be nice to get some traction here. Any suggestions for a better function name?
#27
@
8 years ago
How about simply call_shortcode( $tag, $atts, $content )
? I realize this is only slightly different than the original suggestion, but that's what I came up with before I knew about this ticket.
Here's my implementation: https://gist.github.com/aaemnnosttv/0751dea2121db3a859fa
For what it's worth, I think it would be better return an empty string than a WP_Error
if the shortcode callback isn't callable since this is basically a template function. get_template_part()
doesn't do this, and dealing with a WP_Error
in the template just seems gross, as well as potentially causing real errors if it isn't properly checked for: (PHP Catchable fatal error: Object of class WP_Error could not be converted to string in ...
). A bit worse than not showing anything IMO.
We already have shortcode_exists()
, using a WP_Error
here seems a bit unnecessary, although I admit they do check different things. What if shortcode_exists()
checked if the callback is callable as well?
I trigger a PHP notice in my implementation, but perhaps an action could be fired instead, similar to a wp_mail()
failure?
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 years ago
#29
@
8 years ago
- Milestone changed from 4.8 to 4.8.1
Per yesterday's bug scrub, we're going to punt this to 4.8.1.
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
7 years ago
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
7 years ago
#32
@
7 years ago
- Milestone changed from 4.8.1 to 4.9
Per today's bug scrub, we'll punt this as the focus for 4.8.1 is regressions only.
Introduces
call_shortcode_func()