I'm trying to create a basic short code in Wordpress that will allow me to run PHP on pages. This is what I have so far, but it isn't working. Advice?
The idea is it will be [php] Insert PHP here [/php']
<?php
function php_shortcode( $attr, $content = null ) {
return '<?php' . $content . '?>';
}
add_shortcode('php', 'php_shortcode');
?>
Thank you.
Sorry to say you are exploring a concept that simply cannot yield success. The PHP that renders the shortcode, cannot "also" render code within itself.
Short codes as standard will filter PHP tags. You can however write php directly into the content editor. Without giving you all the advisories why it's not recommended, you can do something like the following which will allow you to write php into the content editor:
// write '<?php ... ?>' into the editor
add_filter('the_content', 'allow_php', 9);
function allow_php($content) {
if (strpos($content, '<' . '?') !== false) {
ob_start();
eval('?' . '>' . $content);
$content = ob_get_clean();
}
return $content;
}
After thinking about this for a little while I realized there is an obvious solution. So, someone probably has written a plugin to do it and someone has - https://wordpress.org/plugins/inline-php/.
It consists of about 40 lines of PHP. The critical implementation trick is it is not done as a shortcode but as a 'the_content' filter.
add_filter('the_content', 'inline_php', 0);
This is done before other 'the_content' filter processing and avoids all the problems that I encountered trying to use it as a shortcode. Of course, there is still a significant security risk.
Related
I am trying to connect a filepath to my wordpress page.
The filepath I am trying to connect to should be:
'/wp-content/themes/bb-theme-child/php/Hello.php'
Hello.php is:
echo "Hello World"
Here is my code that i have written:
/* SHORTCODE TO HAVE FILES */
add_shortcode('data1', function($atts) {
$atts = 'Some post: ' . include dirname(__Hello.php__) . '/wp-content/themes/bb-theme-child/php/Hello.php';
echo $atts;
});
Whats strange is the output:
echo "Hello!";Some post: 1
Im not sure what Some post: 1 is, nor the reason why Some post comes AFTER Hello.php
The add_shortcode function requires all the output to be returned not echoed
From the docs: https://developer.wordpress.org/reference/functions/add_shortcode/
Note that the function called by the shortcode should never produce an output of any kind. Shortcode functions should return the text that is to be used to replace the shortcode. Producing the output directly will lead to unexpected results. This is similar to the way filter functions should behave, in that they should not produce unexpected side effects from the call since you cannot control when and where they are called from.
That being said, your shortcode should look like:
add_shortcode('data1', function($atts) {
ob_start();
echo 'Some post: ';
include dirname(__Hello.php__) . '/wp-content/themes/bb-theme-child/php/Hello.php';
// do more stuff here maybe ?
return ob_get_clean();
});
!!! Also, make sure your Hello.php file has an open PHP tag before the echo "Hello World" line.
NOTE: Not sure what is your expected output, but this is how I interpreted your code.
You may learn more about WordPress shortcodes from the official docs or from this article I wrote
My users want to be able to have a contact form on their website. Understandable. But it's not really working out.
<?php
function ubbreplace($text){
$text = str_replace("[contact-form]",'<?php include("contactform.php"); ?>',$text);
return $text;
}
?>
The include is not including the contact form. Why is that?
The str_replace function that you're using is working as expected. If you don't see anything in your browser, view the source code and you'll see a <?php tag within your HTML code.
The output is the stuff that normally goes to your browser. A buffer is a cache of data. Output buffer is a cache of data that would have normally gone to your browser, but didn't because you buffered it instead.
To get your desired results, we need to grab the contents of the contactform.php file and replace [contact-form] with those contents. We can do this by capturing the output from the contactform.php into a variable and using that variable as the replacement.
<?php
function ubbreplace($text){
if(strpos($text, '[contact-form]') !== false) {
ob_start();
require 'contactform.php';
$replace = ob_get_contents();
ob_end_clean();
$text = str_replace('[contact-form]', $replace, $text);
}
return $text;
}
$content = ubbreplace('Hello world! [contact-form]');
echo $content;
?>
You are approaching the concept entirely from the wrong end, what you are doing is working with strings, and these strings will not be processed by PHP as functions, or includes or other core markup.
you can insert variables into a string but this happens at execution time, and the string will not then be re-executed (and also ignores the fact the include is not a variable at all but is a language construct).
So, what can you do about this? Well - rearrange your code with the logic that:
You have a string you want to find, and then act once it's been found.
So, to do this try this code logic (customise, obviously). You want to find the "flag" you have set and then replace it with a correct marker,
<?php
if( stripos($text,"[contact-form]") !== false){
include("contactform.php");
}
?>
The above will maybe not do exactly as you intend, because its behaviour depends heavily on what is inside the included PHP file.
You will maybe have to rearrange your include contents (you can return data from an include if you really need to, but I don't really recommend that).
As a small improvement I would also recommend using mb_stripos() function instead of the standard stripos();.
So to get a cleaner more usable result, set the contents of the include to a variable such as $contactForm = "HTML contact form data"; and then always run the include, but only output the contents if the flag is found:
include contains:
$contactForm = "Some HTML contact data";
parent file contains:
<?php
include("contactform.php");
if( stripos($text,"[contact-form]") !== false){
print $contactForm;
}
?>
Or what is very probably easier for you to implement is:
<?php
include("contactform.php");
function ubbreplace($text){
$text = str_replace("[contact-form]",$contactForm,$text);
return $text;
}
?>
Include in the PHP manual, Please note references to return values
Splash58's Answer (and Brogans Answer) of using output buffering is also a perfectly
good solution and saves a lot of the effort of quantifying included output into
varaibles in my answer, although my answer is primarily to explain the
purpose and the failings of your original question.
Given a completely open option I would choose to use Output buffering
to solve this issue but you do need to know what's going on, so if
output buffering is new to you definitely read up on it first.
function ubbreplace($text){
if (strpos($text, "[contact-form]") !== false) {
ob_start();
include("contactform.php");
$replace = ob_get_contents();
ob_end_clean();
$text = str_replace("[contact-form]", $replace, $text);
}
return $text;
}
I know eval() in php is to evaluate php code inside string. I also was create a simple template class with eval. But, in practice this way is not comfortable. Very hard to maintain. So, here the simple short snippet code as example
function render($view,$data)
{
extract($data);
ob_start();
include SOMEPATH . 'views/' . $view . EXT;
$result = ob_get_contents();
ob_end_clean();
$result = str_replace('<cihtml name="apa">',file_get_contents( SOMEPATH . '/views/sample.php' ),$result);
echo eval( '?>' . $result);
}
I can render it. But in some case, there is always problem where eval get error with specific reason.
Now, what I need here is the concept template parser without eval() function. Thanks for your advance.
Why reinvent the weel? Most people use frameworks for these kind of things.
Look into
http://phalconphp.com/
http://docs.phalconphp.com/en/latest/reference/volt.html
Through research, I've discovered this question has been asked on multiple occasions, however, my instance is a bit different. I'm attempting to add a character limit to a pre-existing customer environment with the following elseif:
elseif(get_post_type() == 'post') {
echo '<p class="excerpt">';
the_excerpt();
echo '</p>';
}
I attempted to use a couple of methods through functions, however, I've been unable to find a resolution. I'm not natively a PHP developer, so I'm learning as I go here and hoping a fellow develop can help resolve this question and provide a brief description of how to handle this in the future.
Thanks!
P.S. - I read the documentation here: http://codex.wordpress.org/Conditional_Tags and wasn't able to make it work without breaking the rest of the else statement.
By default, excerpt length is set to 55 words. To change excerpt length to 20 words using excerpt_length filter, add the following code to functions.php file in your theme:
function custom_excerpt_length( $length ) {
return 20;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
http://codex.wordpress.org/Function_Reference/the_excerpt
Use get_the_excerpt to return the text without printing it, and chop it to the length you want with substr:
elseif(get_post_type() == 'post') {
echo '<p class="excerpt">';
$excerpt = get_the_excerpt();
$limit = 100;
if (strlen($excerpt) > $limit) {
echo substr($excerpt, 0, $limit), '[...]';
} else {
echo $excerpt;
}
echo '</p>';
}
Lots of ways to do this.
Easy Way:
Install the Advanced Excerpt plugin and replace the_excerpt(); with the_advanced_excerpt() and configure as needed in Settings -> Excerpt in admin panel (or use string query vars in the function call). This also lets you do a lot of stuff like have custom "read more" link (or exclude it), add '...' or some other text at the end, strip or allow specific html tags, etc.
Tedious Way:
You can use substr PHP function (docs) in conjunction with get_the_content(); or get_the_excerpt() to trim it to however many characters you want (or do whatever else you want to it) like freejosh's answer.
Advanced / Clean Way:
Filter the excerpt length to however many characters you want using the method described in Srikanth's answer (this is my preferred way, unless you need some of the Advanced Excerpt options like use_words etc).
I'm using the Cart66 Wordpress plugin, and I'm trying to include a variable in a shortcode, you can see the code below:
$price = do_shortcode('[add_to_cart item="test-item" showprice="only" text=""]').' test';
echo do_shortcode('[add_to_cart item="test-item" showprice="no" quantity="1" text="'.$price.'" ]');
I've done some googling, and apparently this is the right way to include variables in Wordpress shortcodes, but this doesn't seem to work for me, Cart66 just falls back and uses the default "Add to Cart" text instead of the text defined in the shortcode above.
Can anyone see where I'm going wrong here?
As you have googled to add text in the shortcode is correct but not fully correct.
You have used "do_shortcode()" function which is used to replace the shortcode functionality and display its functionality in frontend. But, if you want to add a parameter in a shortcode and make it working you need to change the shortcode functionality a bit.
You have to find shortcode in your files containing the shortcode's functionality:
Find code something like below:
add_shortcode('add_to_cart','function_name');
function function_name($atts)
{
$atts //-- will be used to add parameters as you needed
}
You can use PHP's Output Buffering control
PS: do_shortcode() does not natively echo the output; whatever is bound on that action may echo by itself as well, which is when you either (A) edit the plugin, or (B) use OB.
I think there were some weird characters in the returend value that were causing issues, I used the Expression code below, and it seemed to solve my issue:
$value = substr(do_shortcode('[add_to_cart item="test-item" showprice="only" text=""]'), 0, 4).' Test';
$patterns = array();
$patterns[0] = '/"/';
$replacements = array();
$replacements[2] = ' ';
$value = preg_replace($patterns, $replacements, html_entity_decode($price, ENT_QUOTES));
echo do_shortcode('[add_to_cart item="test-item" showprice="no" quantity="1" text="'.$price.'" ]');
Needless to say this was a very ... complicated solution. I ended up using some good old SQL by utilising Wordpresses WPDB class. Turning about 7 lines of code into 2:
$priceValue = $wpdb->get_var("SELECT price FROM wp_cart66_products WHERE id = x");
echo do_shortcode('[add_to_cart item="test-item" showprice="no" quantity="1" text="£'.$priceValue.' Membership" ]');
This is a much better solution, I wouldn't recommend trying to use shortcodes for things they weren't intended to be used for.
The ‘add_shortcode’ function does not allow you to use external variables. It operates with a local scope, so any variables declared INSIDE will be recognized, but any variables OUTSIDE will not be recognized. If you want to use an external variable you will need to use global.
Using global on your external variable will pull it within scope and allow you to use it within the add_shortcode function! :)
$greeting = "hello world!"; //external variable
function run_greeting() {
global $greeting //pulls variable within scope
echo $greeting;
}
add_shortcode( 'greeting_shortcode', 'run_greeting' );