I have this function:
<?php myWidget() { ?>
<div id="<?php echo $args['widget_id']; ?>">
<p>Something</p>
</div>
<?php } ?>
(widget_id is Wordpress core function so I have no direct access to that, it just simply generates widgets name)
I wanted to add my widget as a shortcode so needed to create another function:
function myWidget_shortcode( $atts ) {
extract( shortcode_atts( array(
/* attributes here */
), $atts ) );
ob_start();
the_widget(myWidget);
return ob_get_clean();
}
the_widget just simply calls widget called myWidget.
The point is, everything works good, but id=" " is always empty when I use the second code.
I know it's a Wordpress question, but I believe this has more to do with my PHP code.
Any ideas?
Judging from your last comment the problem is that $args is not set and since the ID is set from $args it will "".
You have to find out where $args is set and either make sure that part is run or set it your self.
$args in this case is not arguments to myWidget method but a global array.
Check if it exists at all
isset($args)
My guess is its a scope issue. $args isnt inside the function. Try passing it to the function
Related
On my wordpress page (which I will use as a template to duplicate) I need to use a custom field 'dropbox' as an href url.
I created a PHP Code Snippet (shortcode) to use as a replacement for the url: [xyz-ips snippet="dropbox"]
Here is the PHP within the shortcode:
<?php the_field('dropbox'); ?>
Here is the code on the page:
download the documents
This short code will not pass the url from custom field to the href. Any thoughts?
Thanks in advance.
Your shortcode should be working if it's as you describe, but you should note shortcodes need to return values, not echo them. You didn't post the code you're using to register it, so I can only assume you're echoing content instead of returning it.
With that said,
I would just make the shortcode echo out the whole entire link, that way you have a bit more granular control over the whole thing:
add_shortcode( 'xyz-ips-link', function( $atts ){
extract( shortcode_atts( array(
'snippet' => 'dropbox',
'text' => 'Download the Documents',
'target' => '_new',
), $atts ) );
$link = sprintf( '%s', get_field( $snippet ), $target, $text );
return $link;
});
This will let you just use [xyz-ips-link] anywhere in your content,
or <?php echo do_shortcode( '[xyz-ips-link]' ); ?> in your page templates.
It also gives you more granular control over the content of the link, such as [xyz-ips-link snippet="dropbox" text="Some Alternative Text"].
You'll also note I'm using get_field() instead of the_field(). WordPress (and ACF) both have get_ functions that return a variable for you to use, and the_ functions which get and output the variable by default.
You can see an example of this code here, Note:I don't have ACF installed, so I replaced the href attribute)
Hi Please try it may work for you .
echo do_shortcode('dropbox');
Try it
$dropdown = get_the_field('dropbox');
echo do_shortcode($dropbox);
OR
$dropdown = get_field('dropbox');
echo do_shortcode($dropbox);
So it turns out there is a specific way to call url custom fields (ACF). I inserted the below code into a PHP Code shortcode. This worked like a charm!
<?php
$link = get_field('dropbox');
if( $link ): ?>
<a class="button" href="<?php echo $link; ?>" target="_new">download documents</a>
<?php endif; ?>
Working on a Wordpress site and where I need to have a post with php content.
I figured out that this is only possible with a plugin or a shortcode in the functions.php
Googled around, tried a lot but it isn't working out, so i definitely doing something wrong.
code I have in functions.php:
function anniversary_link($text) {
$url = the_permalink();
return "<a href='$url'>$text</a>";
}
add_shortcode('permalink', 'anniversary_link');
And the post I have:
and the result I get when clicking the link:
The shortcode has to reference to the single.php page and al the static code's references to the single.php page is just:
<?php the_permalink() ;?>
Is this te 'correct' way to use href on a post (is there a better/cleaner way to get this working)?
Edit
Updated my code thanks to nathan Edit edit: in functions.php
function anniversary_link( $atts ) {
$atts = shortcode_atts( array(
'text' => '',
), $atts, 'permalink' );
$url = get_permalink();
return '' . $atts['text'] . '';
}
add_shortcode('permalink', 'anniversary_link');
And how I use this short code inside a post (I think that I incorrectly use the shortcode):
Result:
Edit Edit
This is how I call the dynamic anniversary post:
<?php echo get_posts(array( 'category_name' => 'Anniversary' ))[0]->post_content ;?>
(inside the header)
solution thanks to nathan
Reading through the code you've posted I see three issues.
The way you're accessing the 'text' attribute.
The function you're using to get the permalink.
The way you're inserting your shortcode into your content.
Shortcode Attributes
The first parameter of a shortcode callback should be an array of attributes, not a single string. Naming your parameter $text has no bearing on the value and won't pull the text attribute of your shortcode.
Change the name of your parameter from $text to $atts and set a default value for the text attribute. Setting a default value is a good practice with shortcodes and can be done using the shortcode_atts() function.
Return vs. Output Functions
The second issue is your use of the_permalink(). the_permalink() doesn't return a permalink but outputs it directly instead. As such you can't assign it to a variable.
The new function
function anniversary_link( $atts ) {
// Set defaults where needed
$atts = shortcode_atts( array(
'text' => '',
), $atts, 'permalink' );
// Replace the_permalink().
// Given the level of simplicity it doesn't need it's own variable.
$url = get_permalink();
// Put together a new return statement.
// Various ways this could be formatted. I went with something clear and easy to understand.
return '' . $atts['text'] . '';
}
Usage
In your code you're using the shortcode inside the href attribute of a link. The shortcode returns a full link, not a URL, and therefore shouldn't be inside another a tag.
Example:
[permalink text="My Link Text"]
// Outputs My Link Text
I've created a short code that I'm trying to pass an attribute into, but I don't seem to be receiving the value on the other end.
Here's what I've got below;
function list_display($atts) {
extract( shortcode_atts(
array(
'pageName' => 'No Page Received',
), $atts )
);
echo $pageName;
add_shortcode('list-briefings-display', 'list_display');
}
and the shortcode being used is
[list-display pageName="My Page Name"]
and I'm running a require_once from functions.php
require_once ( TEMPLATEPATH. '/includes/list-display.php' );
But what I'm seeing on the screen is 'No Page Received', can anyone think of something I might've missed?
There is more content being generated by the shortcode, which I have't included, that's rendering fine. So it just seems to be something to do with how I've passed the attribute.
Any help is appreciated.
function list_display($atts) {
$atts = shortcode_atts( array(
'pagename' => 'No Page Received'
), $atts );
extract($atts);
echo $pagename;
}
add_shortcode('list-display', 'list_display');
You'll probably want to use "return" instead of "echo" if you're using the shortcode within pages and posts.. Echo could cause it to send output to the screen a little too early and won't end up exactly where you may be expecting it to be.
There was also a little formatting issue in your code that I've corrected, mainly trying to use add_shortcode() from within the very same function you're trying to reference. I also changed the first parameter of add_shortcode() to the shortcode you were trying to use in your example.
I have created a widget and so far it only displays on the home page. However I want it to appear on the post page, and only if the user has inputted a parameter.
class My_Widget extends WP_Widget {
function __construct() {
$widget_ops = array ('description' => __ ( 'Lorem ipsum' ) );
parent::__construct ( 'exampl', __ ( 'Example' ), $widget_ops );
}
function widget($args, $instance) {
extract ( $args );
$title = apply_filters ( 'widget_title', empty ( $instance ['title'] ) ? ' ' : $instance ['title'] );
# Before the widget
echo $before_widget;
# The title
if ($title)
echo $before_title . $title . $after_title;
# Make the Hello World Example widget
echo isset($instance['foo'])?$instance['foo']:'foo';
echo isset($instance['bar'])?$instance['bar']:'bar';
# After the widget
echo $after_widget;
}
//The global widget options
function form($instance){
/* Set up some default widget settings. */
$defaults = array( 'foo' => 'oof', 'bar' => 'rab');
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p>
<label for="<?php echo $this->get_field_id( 'foo' ); ?>"><!--shortened... -->
</p>
<?php
}
}
function my_init() {
register_widget ( 'My_Widget' );
}
add_action ( "widgets_init", "my_init" );
Now the widget appears in the home page on the right, the default options are treated correctly.
It does not appear on the post page however. ("Hello world! Welcome to WordPress. This is your first post...")
A) How can I make it appear only on the post page
B) How can I control the parameters on a per post level
Example: The global setting "color" should be 'green', controlled on the widgets page. however in the post page I want a textarea "poemoftheday", if it's not empty it should show up on the sidebar using the global "color" 'green', but depending on the post, the "poemoftheday" will be different or not present
My Problems All the WordPress terms and version have made it really hard to find out the correct current solution. I've been working on this for 7 hours now and I'm really stuck. Not asking people to code for me, but I need to know the right terms and methods I should be using. Pointers to tutorials/documentations that solve fit my requirements greatly appreciated (there are sooo many tutorials, but they all behave different from the behaviour I'm looking for)
Visually
^This is where the global configuration is, great
^This is where I'd like to have the per post configuration
^This is where it's appearing right now - displaying good, position no good
^This is where I'd like it to appear
So here's how I solved it after 5 days.
To write store per_post vars I had to use the function
In my class constructor i added the hook add_action ( 'add_my_meta_box', array (__CLASS__, 'add_my_meta_box') );
create the callback function add_my_meta_box($page) in my class
In that callback amongst other things add_meta_box ( 'My Widget', 'My box', array (__CLASS__, 'render_meta_box' ), $page);
All values are read and stored with global $post; and the wordpress functions get_post_meta ($post->ID, 'my_var',true ) and update_post_meta ($post->ID, 'my_var', $value )
To make sure that my widget only appears on a single post page I used the check
if(is_single()) before echoing the widget
have an interesting conundrum. I need to load about 8 javascript files and the same number of styles for my plugin. These are only needed where ever my shortcode is ran.
I've tried to load them with print_styles and print_scripts but they aren't rendering properly, plus to do so breaks xhtml validation. So at the moment they load on every page and due to the number of files needed its not feasible to leave it like this.
On another project I wrote a function into my plugin's index.php file that would take the current page, search it for my shortcode and if found only then would it print the scripts, but this is an ugly hack.
Has anybody got any suggestions or solutions?
any help would be appreciated,
regards,
Daithi
to answer my own question... I had it write the first time. You have to search each page to check that your shortcode is being used. This has to be done when page data is loaded and before page is displayed. To me it is complete overkill on the system, but unfortunately it is the way it is. I got this information from:
get_shortcode_regex
and
old nabble
So first:
add_action('template_redirect','wp_my_shortcode_head');
then:
function wp_my_shortcode_head(){
global $posts;
$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $posts[0]->post_content, $matches);
if (is_array($matches) && $matches[2] == 'YOURSHORTCODE') {
//shortcode is being used
}
}
replace 'YOURSHORTCODE' with the name of your shortcode and add your wp_enqueue_scripts into where it says //shortcode is being used.
I read a solution in here: http://scribu.net/wordpress/conditional-script-loading-revisited.html
Basically if using wordpress 3.3 you can enqueue your scripts in your short code function.
function my_shortcode($atts){
wp_enqueue_script( 'my-script', plugins_url( 'plugin_name/js/script.js' ), array('jquery'), NULL, true);
// if you add a css it will be added to the footer
//wp_enqueue_style( 'my-css', plugins_url( 'plugin_name/css/style.css' ) );
//the rest of shortcode functionality
}
Loading Scripts and Styles Dynamically Per Page Using a Shortcode
Advantages
Does not search through all the posts everytime the shortcode is called.
Able to add styles as well as scripts dynamically only when shortcode is on the page.
Does not use regexes since they tend to be slower than strstr() or strpos(). If you need to pickup args then you should use the shortcode regex mentioned above.
Reduces file calls
Explanation of Code
Finds the shortcodes on page using the save_post hook only when the post is not a revision and matches the specified post_type.
Saves the found post ids as an array using add_option() with autoload set to yes unless the entry is already present. Then it will use update_option().
Uses hook wp_enqueue_scripts to call our add_scripts_and_styles() function.
That function then calls get_option() to retrieve our array of page ids. If the current $page_id is in the $option_id_array then it adds the scripts and styles.
Please note: I converted the code from OOP Namespaced classes so I may have missed something. Let me know in the comments if I did.
Code Example: Finding Shortcode Occurences
function find_shortcode_occurences($shortcode, $post_type = 'page')
{
$found_ids = array();
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => -1,
);
$query_result = new WP_Query($args);
foreach ($query_result->posts as $post) {
if (false !== strpos($post->post_content, $shortcode)) {
$found_ids[] = $post->ID;
}
}
return $found_ids;
}
function save_option_shortcode_post_id_array( $post_id )
{
if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
return;
}
$option_name = 'yourprefix-yourshortcode';
$id_array = find_shortcode_occurences($option_name);
$autoload = 'yes';
if (false == add_option($option_name, $id_array, '', $autoload)) update_option($option_name, $id_array);
}
add_action('save_post', 'save_option_shortcode_id_array' );
Code Example: Shortcode Dynamically Include Scripts and Styles
function yourshortcode_add_scripts_and_styles() {
$page_id = get_the_ID();
$option_id_array = get_option('yourprefix-yourshortcode');
if (in_array($page_id, $option_id_array)) {
wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
wp_enqueue_style( $handle, $src , $deps);
}
}
add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');
Just read this tutorial over here: http://scribu.net/wordpress/optimal-script-loading.html
Seems to be the best way.
add_action('init', 'register_my_script');
add_action('wp_footer', 'print_my_script');
function register_my_script() {
wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
}
function print_my_script() {
global $add_my_script;
if ( ! $add_my_script )
return;
wp_print_scripts('my-script');
}
In this case, the script will be enqueued only if the $add_my_script
global was set at some point during the rendering of the page.
add_shortcode('myshortcode', 'my_shortcode_handler');
function my_shortcode_handler($atts) {
global $add_my_script;
$add_my_script = true;
// actual shortcode handling here
}
So, the script will be added if [myshortcode ...] was found in any of
the posts on the current page.
Load Scripts and Styles if Post/Page has Short Code
The best solution is to load the files into the page header if, and only if, the current post or page has the short code inside its content. And that’s exactly what the following function does:
function flip_register_frontend_assets()
{
//register your scripts and styles here
wp_register_style('pp_font','plugin_styles.css', null, null, 'all');
global $post;
//check whether your content has shortcode
if(isset($post->post_content) && has_shortcode( $post->post_content, 'your-
shortcode')){
//Enqueue your scripts and styles here
wp_enqueue_style( 'pp_font');
}
}
Simply place this function inside of one of your plugin files and you’re good to go.
You will need to replace [your-shortcode] with the short code you want to search for, and you will also need to replace plugin_styles.css with your stylesheet name.
You can just use this code to check if the shortcode is implemented in page content or in sidebar widgets.
<?php
if ( shortcode_exists( 'gallery' ) ) {
// The [gallery] short code exists.
}
?>
I use WordPress Version 5.4 with OOP style of code i dont know if this affect why none of the above solutions didn't work for me so i come up with this solution:
public function enqueue_scripts() {
global $post;
//error_log( print_r( $post, true ) );
//error_log( print_r( $post->post_content, true ) );
//error_log( print_r( strpos($post->post_content, '[YOUR_SHORTCODE]'),true));
if ( is_a( $post, 'WP_Post' ) && strpos($post->post_content, '[YOUR_SHORTCODE]') )
{
wp_register_style('my-css', $_css_url);
wp_register_script('my-js', $_js_url);
}
}
Hope this help someone.
How many pages are these scripts going to be loaded on? Would it be feasible to maintain an array of pages, and only load the scripts/stylesheets when the current page is in the array?
Otherwise, without scanning the code there is no way to do this, as WP doesn't even know the shortcode exists until well into the page load.
BraedenP is right, I'm pretty sure there is no way to detect shortcode usage at the execution time of wp_enqueue_scripts / when the stylesheets load.
Is there any reason you must do this in 8 files? One would just be more efficient, then it may not be a problem to load it on every page.
You could consider a PHP stylesheet solution that only executes certain styles if needed. A css.php file may resemble:
<?php
header("content-type: text/css");
/* You can require the blog header to refer to WP variables and make queries */
//require '../../../wp-blog-header.php';
$css = '';
$css .= file_get_contents('style.css');
/* Consider using GET variables or querying a variable in the WP database to determine which stylesheets should be loaded. You could add an option to the backend that allows a stylesheet to be turned on or off. */
if($condition1 == TRUE) $css .= file_get_contents('condition1.css');
if($condition2 == TRUE) $css .= file_get_contents('condition2.css');
?>
Less scripts and less stylesheets means less http requests and a faster load time.