Plugin content always on top of post WordPress - php

I'm trying to make a WordPress plugin. Well, actually it's done and fully working, except one thing.
I have added a shortcode for the plugin. But no matter where in the content I call this shortcode, the contents it gets are always on top of the post, instead of where I placed the tag.
The code that outputs something:
public static function showIncomingSearches(){
global $id;
$arSearches = self::getArObj(array('wp_post_id' => $id));
ob_start();
if(!empty($arSearches)){
$str = '<ul>' . PHP_EOL;
foreach($arSearches as $oSearch){
$str .= '<li>'.htmlspecialchars($oSearch->searchterm).'</li>' . PHP_EOL;
}
$str .= '</ul>';
if(!empty($arSearches))
echo $str;
} else {
echo ' ';
}
return ob_get_clean();
}
And the shortcode functionality:
add_shortcode('show_incoming_searches', 'checkReferrer');
function checkReferrer(){
incomingSearches::checkReferrer();
echo incomingSearches::showIncomingSearches();
}
What I want to know though, is why it is always on top of the content?

Your shortcode code needs to return the content, not echo it.
function checkReferrer(){
incomingSearches::checkReferrer();
return incomingSearches::showIncomingSearches();
}

Related

Yii2: Global variable in view

I'm need to concatenate lines for later output (markdown processing...). This is why I use a function l() and a global variable $content.
My view code:
$content = "";
function l($line="") {
global $content;
$content .= $line."\n";
}
l("hello");
echo "+";
echo $content;
echo "-";
outputs
+-
I'd expect:
+Hello-
Why? What am I doing wrong?
I am using PHP 7.2.6
EDIT:
There are several PHP related answers as this one. But they don't help. I suppose the problem is related to Yii2 and more specific to Yii2 view handling.
Found the solution! Crazy!
Yii2 renders the view inside an object instance.
This means, the PHP variable declaration
$content = "";
is not global but local to the rendering context.
The solution for question is to make the variable declaration in the view global, too:
global $content = "";
The working code inside the view looks like this now:
global $content = "";
function l($line="") {
global $content;
$content .= $line."\n";
}
l("hello");
echo "+";
echo $content;
echo "-";
Bingo!

php best practices for returning multiple lines of content in an IF statement

I am writing a php plugin for wordpress. I'm trying to be mindful of clean coding and want to know the best practice for returning several lines of HTML code in an IF statement.
Obviously I know about echo but I thought I had seen a technique like this used, but it doesn't seem to work for me. The idea being that you create several $content variables and then return it outside of the IF statement.
function signup() {
if(!Skizzar_Registration::is_skizzar_site_active()) {
$content = '<div class="signup">';
$content .= '<h1>Sign up</h1>';
$content .= '</div>';
} else {
$content = '<div class="signed_up">you are already signed up</div>';
}
return $content;
}
Currently though this returns nothing when I call the function
As you have already discovered, the specific issue is that you are not ecxhoing the data.
As per your followon question (which is prefered, return or echo), in wordpress there seems to be a convention where both options are offered with the functions named accordingly:
//echos
function the_signup_form(){
echo get_the_signup_form();
}
//returns
function get_the_signup_form(){
if(!Skizzar_Registration::is_skizzar_site_active()) {
$content = '<div class="signup">';
$content .= '<h1>Sign up</h1>';
$content .= '</div>';
} else {
$content = '<div class="signed_up">you are already signed up</div>';
}
return $content;
}

PHP - Inject script into the <head>

Run into a bit of a sticky situation which I can't seem to wrap my finger around. Basically what I am trying to achieve is having the ability to inject different Javascript files on different page.
Some simple, random example:
Page 1: import jquery.js
Page 2: import mootools.js
So what I have done is, I've created a function called addScript() like so:
function addScript($file) {
$script = '';
$script .= '<script src="'. REL_PATH . '/path/to/file/' . $file . '">';
$script .= '</script>';
return $script;
}
so if I call addScript('jquery.min'); it, outputs correctly.
What I now want to do is replace the closing </head> tag with the output from the above function. If I do the following then it works fine:
ob_start();
require_once("models/header.php");
$contents = ob_get_contents();
ob_end_clean();
echo str_replace('</head>', addScript('jquery.js') . '</head>', $contents);
However I would like this to be a little more dynamic as there may be multiple script that I need to inject on each page like so:
addScript('script.js');
addScript('script2.js');
addScript('script3.js');
I then thought of creating a getHead() function with a foreach loop inside and returning str_replace there instead but this did not work.
Can anyone guide my in the direction to dynamically inject as many script as required and output the last bit of the head?
Why not do something like this:
class Assets {
private static $css = array();
private static $js = array();
static function add_style($path) {
self::$css[] = $path;
}
static function add_script($path) {
self::$js[] = $path;
}
static function get_styles() {
$output = '';
foreach(self::$css as $path) {
$ouput .= '<link rel="stylesheet" href="'. $path .'" />' . "\n";
}
return $ouput;
}
static function get_scripts() {
$output = '';
foreach(self::$js as $path) {
$ouput .= '<script type="text/javascript" src="'. $path .'"></script>' . "\n";
}
return $ouput;
}
}
Then anywhere in your project:
Assets::add_style('path/to/style.css');
Assets::add_script('path/to/jquery.js');
And in header.php:
<head>
<!-- other header stuff -->
<?php echo Assets::get_styles(); ?>
<?php echo Assets::get_scripts(); ?>
</head>
Is much more convenient, and you can can extend the class to do more fancy stuff.
Disclaimer: there is much debate about using static vars, as they look like globals. I agree, but this is quick-and-dirty and works no matter what kind of framework you use. You can also make the variables oldschool instance vars, but then you'll have to pass the assets object to the header.php as well.
What's wrong with the following??
echo str_replace('</head>',
addScript('jquery.js').
addScript('jquer1.js').
addScript('jquer2.js').
addScript('jquer3.js').
'</head>', $contents);
How about you put the ob_start(); in header.php. Then your function is:
function addScript($file) {
$script = '<script src="'. REL_PATH . '/path/to/file/' . $file . '"></script>';
echo str_replace('</head>', addScript('jquery.js') . '</head>', ob_get_clean());
}
Then:
addScript('script.js');
This method keeps the output buffer going and you can manipulate it later in the script whenever you want. just as you do with the addScript().

Using str_replace within an already-existing function?

So right now, I have a simple function that I use to call some text content:
function htmlstuff() { ?>
<p>html text content here</p>
<? }
And on a page I call the text using:
<?php htmlstuff() ?>
Now, I need to figure out how to use "search and replace" for whatever text is in the function. I've tried things like
function str_replace($search,$replace,htmlstuff())
but I obviously don't know what the heck I'm doing. Is there any simple way to just search the text within the function and search/replace?
what do you really want to do?
if you want to search and replace and in the return variable of your htmlstuff function then
you are not too far away from the correct answer.
function htmlstuff() {
$htmlstuff = "<p>html text content here</p>";
return $htmlstuff;
}
echo htmlstuff();
str_replace($search,$replace,htmlstuff());
this should do the trick
if you just want to make the function htmlstuff more dynamic, then you should take a different approach. something like this:
function htmlstuff($html) {
$htmlstuff = "<p>".$html."</p>";
return $htmlstuff;
}
echo htmlstuff("html text content here");
It would seem like this:
function htmlstuff ($content = "Default text goes here")
{
echo "<p>" . $content . "</p>";
}
and then on another call you just htmlstuff("New text to go there");
And if I'm wrong correct me to solve the problem
<?php
$html_stuff = htmlstuff();
$search_for = "Hello, world!";
$replace_with = "Goodbye, world!";
$html_stuff = str_replace($search_for, $replace_with, $html_stuff);
echo $html_stuff;
function htmlstuff() {
echo '<p>html text content here</p> ';
}

How do I populate a variable using a function?

I have the code below on a page basically what I'm trying to do is fill $content variable using the function pagecontent. Anything inside pagecontent function should be added to the $content variable and then my theme system will take that $content and put it in theme. From the answers below it seems you guys think I want the html and php inside the actual function I don't.
This function below is for pagecontent and is what I'm currently trying to use to populate $content.
function pagecontent()
{
return $pagecontent;
}
<?php
//starts the pagecontent and anything inside should be inside the variable is what I want
$content = pagecontent() {
?>
I want anything is this area whether it be PHP or HTML added to $content using pagecontent() function above.
<?php
}///this ends pagecontent
echo functional($content, 'Home');
?>
I think you're looking for output buffering.
<?
// Start output buffering
ob_start();
?> Do all your text here
<? echo 'Or even PHP output ?>
And some more, including <b>HTML</b>
<?
// Get the buffered content into your variable
$content = ob_get_contents();
// Clear the buffer.
ob_get_clean();
// Feed $content to whatever template engine.
echo functional($content, 'Home');
As you are obviously a beginner here's a much simplified, working version to get you started.
function pageContent()
{
$html = '<h1>Added from pageContent function</h1>';
$html .= '<p>Funky eh?</p>';
return $html;
}
$content = pageContent();
echo $content;
The rest of the code you post is superfluous to your problem. Get the bare minimum working first then move on from there.
Way 1:
function page_content(){
ob_start(); ?>
<h1>Hello World!</h1>
<?php
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
$content .= page_content();
Way 2:
function page_content( & $content ){
ob_start(); ?>
<h1>Hello World!</h1>
<?php
$buffer = ob_get_contents();
ob_end_clean();
$content .= $buffer;
}
$content = '';
page_content( $content );
Way 3:
function echo_page_content( $name = 'John Doe' ){
return <<<END
<h1>Hello $name!</h1>
END;
}
echo_page_content( );

Categories