shortcode - within a shortcode WP PHP HTML - php

I wanted to know if there is a way for the chocolate to be directed to two different parameters? And I will explain
this shortcode [group skill] => return $skill;
This is the second shortcode [group lang] => return $lang;
I have a group that I opened through ACF and I want to take out a shortcode every time to a different place, to the place intended for it
This is the original code
<?php
add_shortcode('group', function ($atts) {
$group_field = get_field('info_global_course');
if ($group_field):
$attributes = shortcode_atts([
'level_skill' => $group_field[level_skill],
'lang' => $group_field[lang],
'if_id_true' => $group_field[if_id_true]
], $atts);
/* I thought about this way, maybe it's not a rally, but maybe it will give you an idea to help me a little
* return $attributes['level_skill'];
* return $attributes['lang'];
*/
endif;
});
?>
editing:
After failed attempts, I preferred to build the design on top of HTML (previously it was built in the form of Elementor)
I have the following code:
<?php
/*************************************
* Returns the values ​​from a certain group of the post
*************************************/
add_shortcode('group', function ($atts,$shortcode_twoo,$shortcode_three) {
$group_field = get_field('info_global_course');
if ($group_field):
$attributes = shortcode_atts([
'level_skill' => $group_field[level_skill],
'lang' => $group_field[lang],
'if_id_true' => $group_field[if_id_true]
], $atts);
return '
<div>
<div class="level_skill border_bottom">
<span class="box_left"><i aria-hidden="true" class="far fa-clock"></i> time </span>
<span class="box_right">'.$shortcode .'</span>
</div>
<div class="video border_bottom">
<span class="box_left"><i aria-hidden="true" class="fas fa-video"></i> Study chapters </span>
<span class="box_right">'.$shortcode1.'</span>
</div>
<div class="studants border_bottom">
<span class="box_left"><i aria-hidden="true" class="fas fa-user-graduate"></i> Registered students</span>
<span class="box_right">100</span>
</div>
<div class="level_skill border_bottom">
<span class="box_left"><i aria-hidden="true" class="fab fa-superpowers"></i> level skill</span>
<span class="box_right">מתקדמים</span>
</div>
<div class="lang border_bottom">
<span class="box_left"><i aria-hidden="true" class="fas fa-globe"></i>language</span>
<span class="box_right">עברית</span>
</div>
<div class="if_id_true border_bottom">
<span class="box_left"><i aria-hidden="true" class="fas fa-sticky-note"></i> Diploma</span>
<span class="box_right">כן</span>
</div>
</div>
';
endif;
});
?>
The goal is to insert into this array all the shortcodes I will create in the future
That's why I did:
<?php
$shortcode = do_shortcode('[time]');
$shortcode1 = do_shortcode('[chapters]');
?>
or for HTML:
[time]
[chapters]
But then I get stuck on the same issue of how I insert the various SHORTCODE variables

Short Code Definition Class (Create the file with desired name and add the code in to the file.
class MyPlugin_ShortCodes
{
/**
* Register the shortcodes for the public-facing side of the site.
*
* #since 1.0.0
*/
public function register_shortcodes()
{
add_shortcode('group', array($this, 'shortcode'));
}
public function shortcode($attrs, $content = "", $shortcode = "my-plugin")
{
$allAttrs = $attrs;
$attrs = shortcode_atts(array(
'type' => null,
'id' => null,
'code' => null,
), $attrs, $shortcode);
if ($attrs["type"] != null) {
try {
$f = 'do__' . $attrs["type"];
if (method_exists($this, $f))
return $this->$f($attrs, $content, $allAttrs);
return '[The "type" attribute did not match any known shortcode type. Found: ' . $attrs["type"] . ']';
} catch (Exception $ex) {
return json_encode($ex->getMessage());
}
}
return "Don't Know what to process!";
}
function do__skill($attrs, $content, $allAttrs)
{
$html = "Put your skills level here";
return $html;
}
function do__lang($attrs, $content, $allAttrs)
{
$html = "Do Whateaver you want";
return $html;
}
}
Now Add the below lines to your plugin definition file
$plugin_shortcodes = new MyPlugin_ShortCodes();
$this->loader->add_action('init', $plugin_shortcodes, 'register_shortcodes');
Shortcodes could be called like...
do_shortcode('[group type="skill" id="{$ID}"]');
do_shortcode('[group type="lang" id="{$ID}" code="en"]');
do_shortcode('[group type="xxxx"');

Many thanks to everyone who tried to help
I found a nice method to combine all the shortcodes into one shortcode
<?php
/********************
* Consolidation of shortcodes
**********************/
add_shortcode('total_topics_chapters_group',function() {
$output = '';
$output .= do_shortcode('[time]');
$output .= do_shortcode('[chapters]');
$output .= do_shortcode('[group]');
return $output;
});
?>

Related

Replace certain Child value if doesn't contain certain string? or Rewrite XPATH query? Website scrape

Preface: This is the first XPath and DOM script I have ever worked on.
The following code works, to a point.
If the child->nodevalue, which should be price, is empty it throws off the rest of the elements and it just snowballs from there. I have spent hours reading, rewriting and can't come up with a way to fix it.
I am at the point where I think my XPath query could be the issue because I am out of ideas on how to test that is the right child value.
The Content I am scraping looks like this(Actually it looks nothing like this there are 148 lines of HTML for each product but these are the relevant ones):
<div class="some really long class name">
<h2 class="second class">
<a class="a-link-normal s-no-outline" href="TheURLINeed.php">
<span class="a-size-base-plus a-color-base a-text-normal">
The Title I Need
</span>
</a>
</h2>
<span class="a-offscreen">
$1,000,000
</span>
</div>
Here is the code I am using.
$html =file_get_contents('http://localhost:8888/scraper/source.html');
$doc = new \DOMDocument();
$doc->loadHTML($html);
$xpath = new \DOMXpath($doc);
$xpath->preserveWhiteSpace = FALSE;
$nodes= $xpath->query("//a[#class = 'a-link-normal s-no-outline'] | //span[#class = 'a-size-base-plus a-color-base a-text-normal'] | //span[#class = 'a-price']");
$data =[];
foreach ($nodes as $node) {
$url = $node->getAttribute('href');
if(trim($url,"\xc2\xa0 \n \t \r") != ''){
array_push($data,$url);
}
foreach ($node->childNodes as $child) {
if (trim($child->nodeValue, "\xc2\xa0 \n \t \r") != '') {
array_push($data, $child->nodeValue);
}
}
}
$chunks = (array_chunk($data, 4));
foreach($chunks as $chunk) {
$newarray = [
'url' => $chunk[0],
'title' => $chunk[1],
'todaysprice' => $chunk[2],
'hiddenprice' => $chunk[3]
];
echo '<p>' . $newarray['url'] . '<br>' . $newarray['title'] . '<br>' .
$newarray['todaysprice'] . '</p>';
}
Outputs:
URL
Title
Price
URL
Title
Price
URL
Title
URL. <---- "Price was missing so it used the next child node value and now everything from here down is wrong."
Title
Price
URL
I am aware this code is FAR from the right but I had to start somewhere.
If I understand you correctly, you are probably looking for something like the below. For the sake of simplicty, I skipped the array building parts, and just echoed the target data.
So assume your html looks like the one below:
$html = '
<body>
<div class="some really long class name">
<h2 class="second class">
<a class="a-link-normal s-no-outline" href="TheURLINeed.php">
<span class="a-size-base-plus a-color-base a-text-normal">
The Title I Need
</span>
</a>
</h2>
<span class="a-offscreen">
$1,000,000
</span>
</div>
<div class="some really long class name">
<h2 class="second class">
<a class="a-link-normal s-no-outline" href="TheURLINeed2.php">
<span class="a-size-base-plus a-color-base a-text-normal">
The other Title I Need
</span>
</a>
</h2>
</div>
<div class="some really long class name">
<h2 class="second class">
<a class="a-link-normal s-no-outline" href="TheURLINeed3.php">
<span class="a-size-base-plus a-color-base a-text-normal">
The Final Title I Need
</span>
</a>
</h2>
<span class="a-offscreen">
$2,000,000
</span>
</div>
</body>
';
Try this:
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$data = $xpath->query('//h2[#class="second class"]');
foreach($data as $datum){
echo trim($xpath->query('.//a/#href',$datum)[0]->nodeValue),"\r\n";
echo trim($xpath->query('.//a/span',$datum)[0]->nodeValue),"\r\n";
#$price = $xpath->query('./following-sibling::span',$datum);
#EDITED
$price = $xpath->query('./following-sibling::span[#class="a-offscreen"]',$datum);
if ($price->length>0) {
echo trim($price[0]->nodeValue), "\r\n";
} else {
echo("No Price"),"\r\n";
}
echo "\r\n";
};
Output:
TheURLINeed.php
The Title I Need
$1,000,000
TheURLINeed2.php
The other Title I Need
No Price
TheURLINeed3.php
The Final Title I Need
$2,000,000

How to achieve InfiniteScroll in Laravel5

I have found a lot of tutorials but none of them are worked. in my case i have an array of fonts returned from googlefontapi and i'm print it in page successfully
now i want only 10 fonts loaded first time and others on scrolling my code
public function index(){
$url = "https://www.googleapis.com/webfonts/v1/webfonts?key=!";
$result = json_decode(file_get_contents( $url ));
$font_list = "";
foreach ( $result->items as $font )
{
$font_list[] = [
'font_name' => $font->family,
'category' => $font->category,
'variants' => implode(', ', $font->variants),
// subsets
// version
// files
];
}
return view('website_settings')->with('data', $font_list);
}
the view file
<div class="am-fonts">
<ul class="am-fonts-list">
#foreach($data as $fonts)
<li class="abc">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=<?php echo $fonts['font_name'];?>:<?php echo $fonts['variants'];?>">
<div class="am-actions"><span><i class="icon add"></i></span></div>
<div class="am-font-preview" style="font-family: <?php echo $fonts['font_name'];?>;">
Grumpy wizards make toxic brew for the evil Queen and Jack.
</div>
<div class="am-font-details">
<div class="am-font-name">{!! $fonts['font_name'] !!}</div>
<div>12 styles</div>
</div>
</li>
#endforeach
</ul>
</div>

Display image from php

I'm trying to display an image in an html file. Up to now i used an url : http://placehold.it/400x300, it worked fine, now when i try to replace it with image from database it doesn't display anything. the image path is : D:/uwamp/www/project/upload/tcf_animal17.jpg i tried with different path but it doesn't work. i'm not sure where is the problem. i printed the data , this is the good path
html
<?php foreach ($data[0] as $film):?>
<div class = <?= $film['id_film'] ?> >
<div class= "col-lg-3 col-md-4 col-xs-6 thumb filmDiv" >
<a class="thumbnail " id = "filmShow" href= <?= "/project/admin/showFilm/" . $film['id_film']?>>
<p> <?= $film['title_film'] ?> </p>
<img class="img-responsive overlay" src= <?= $film['img'] ?> alt="">
</a>
<a class="" href =<?= "/project/admin/update/" . $film['id_film'] ?> >
<button name="upd" id="upd" type="button" class="btn btn-default">Update</button>
</a>
<a class="delete"name= <?= $film['id_film'] ?> >
<button id="delete" type="button" class="btn btn-default">Delete</button>
</a>
</div>
</div>
<?php endforeach; ?>
Controler :
public function GetLastFilms()
{
$films = $this->film->getFilms();
$lastFilms = $this->film ->getLastFilm();
$dict[0] = $films;
$dict[1] = $lastFilms;
return $dict;
}
public function index()
{
if(isset($_SESSION['login']))
{
$this->generateView($this->GetLastFilms());
}else
{
header('Location: /project/admin/login');
}
}
protected function generateView($data = array())
{
$classeControler = get_class($this);
$controler = str_replace("Controler", "", $classeControler);
$view = new View($this->action, $controler);
$view->generate($data);
}
View :
public function generate($data)
{
$contenu = $this->generateFile($this->viewFile, $data);
$racineWeb = Configuration::get("racineWeb", "/");
$view = $this->generateFile('View/Template/index.php',
array('title' => $this->viewTitle, 'contenu' => $contenu,
'racineWeb' => $racineWeb));
echo $view;
}
private function generateFile($viewFile, $data)
{
if (file_exists($viewFile))
{
extract($data);
ob_start();
require $viewFile;
return ob_get_clean();
}
else
{
throw new Exception("can't find '$viewFile'");
}
}
Your problem is that the path to the image in the database is stored as local path from your machine (D:/uwamp/www/project/upload/tcf_animal17.jpg), where for it to display correctly it needs to be a path relative to the root of your web server documents.
For example, if your web server document root is D:/uwamp/www, then the path of the image you need to store should be project/upload/tcf_animal17.jpg.
Of course if you can't get the image to be stored within the web root, then you always have an option to just dump the content directly, however it's really not a good idea, for performance reasons:
<?php
$mime = image_type_to_mime_type(exif_imagetype(string $image_path));
$data = "data:$mime;base64," . base64_encode(file_get_contents($image_path)); ?>
?>
<img src="<?= $data ?>">
This code is very crude and does no error checking - you'll need to add that for a production-level application.

Dueling Regex and DOM Scripts

I'm learning how to work with Bootstrap and jQuery. It looks like I need to do something like this with my articles in order to get some of the special effects (like toggling sections open and closed)...
<section id="introduction">
<h2 class="h2Article" id="a1" data-toggle="collapse" data-target="#b1"><span class="Article"><span class="label label-primary"><small><span class="only-collapsed glyphicon glyphicon-chevron-down"></span><span class="only-expanded glyphicon glyphicon-remove-sign"></span></small> Introduction</span></span></h2>
<div class="divArticle collapse in article" id="b1">
But I have hundreds of articles to put into my database, and writing all that code would take forever. So I put this in my database instead...
<section id="introduction">
<h2 class="h2Article">Introduction</h2>
<div class="divArticle">
Next, I want to use regex or DOM to insert the missing values (preferably regex, as it's easier to work with). In fact, it was working, but now it isn't.
This is my regex script:
$Content = preg_replace('/<h2 class="h2Article">(.*?)<\/h2>/', '<h2 class="h2Article"><span class="Article"><span class="label label-primary"> <small><span class="only-collapsed glyphicon glyphicon-chevron-down"> </span><span class="only-expanded glyphicon glyphicon-remove-sign"></span> </small> $1</span></h2>', $Content);
$Content = preg_replace('/<h3 class="h3Article" id="(.*?)">(.*?) <\/h3>/', '<h3 id="$1" class="Article"><span class="label label- default">$2</span></h3>', $Content);
$Content = preg_replace('/<div class="divArticle">(.*?)<\/div>/', '<div class="divArticle">$1<div style="margin-bottom: 10px; font-size: 150%; text-align: center;"><span class="only-expanded glyphicon glyphicon-remove- sign"></span></div></div>', $Content);
$Content = str_replace('<!-- EndMainDiv -->', '<div class="divClose" style="margin-bottom: 10px; font-size: 150%; text-align: center;"><span class="only-expanded glyphicon glyphicon-remove-sign"></span></div><!-- EndMainDiv -->', $Content);
And this is what the resulting HTML looks like:
<section id="introduction">
<h2 class="h2Article"><span class="Article"><span class="label label- primary"><small><span class="only-collapsed glyphicon glyphicon-chevron- down"></span><span class="only-expanded glyphicon glyphicon-remove-sign"> </span></small> Introduction</span></h2>
<div class="divArticle">
This is my DOM script:
$i = 1; // initialize counter
// initialize DOMDocument
$dom = new DOMDocument;
#$dom->loadHTML($Content); // load the markup
$sections = $dom->getElementsByTagName('section'); // get all section tags
if($sections->length > 0) { // if there are indeed section tags inside
// work on each section
foreach($sections as $section) { // for each section tag
// $section->setAttribute('id', '#a' . $i); // set id for section tag
// get div inside each section
foreach($section->getElementsByTagName('h2') as $h2) {
if($h2->getAttribute('class') == 'h2Article') { // if this div has class maindiv
$h2->setAttribute('id', 'a' . $i); // set id for div tag
$h2->setAttribute('data-target', '#b' . $i);
// $h2->setAttribute('data-target', '#b' . $i . ',#c' . $i);
}
}
foreach($section->getElementsByTagName('div') as $div) {
if($div->getAttribute('class') == 'divArticle') { // if this div has class divArticle
$div->setAttribute('id', 'b' . $i); // set id for div tag
}
if($div->getAttribute('class') == 'divClose') { // if this div has class maindiv
$div->setAttribute('data-target', '#b' . $i); // set id for div tag
}
}
$i++; // increment counter
}
}
// back to string again, get all contents inside body
$Content = '';
foreach($dom->getElementsByTagName('body')->item(0)->childNodes as $child) {
$Content .= $dom->saveHTML($child); // convert to string and append to the container
}
$Content = str_replace('data-target', 'data-toggle="collapse" data-target', $Content);
// $Content = str_replace('data-target', 'class="SecCon" data- toggle="collapse" data-target', $Content);
$Content = str_replace('<div class="divArticle', '<div class="divArticle collapse in article', $Content);
And this is what the HTML looks like:
<section id="introduction">
<h2 class="h2Article" id="a1" data-toggle="collapse" data- target="#b1">Introduction</h2>
<div class="divArticle collapse in article" id="b1">
The weird thing is, it works when I use the regex and DOM script BOTH, but that's going to be kind of sloppy to work with. Can anyone tell me how to modify either my regex or my DOM to make it do the job by itself?

How do I return more than one value?

I need some help.
I'm not able to use echo because of the structure I've built. I don't have the time to explain why. But my question is, is there any way to return multiple data? lets say this for example:
final public function getCamps()
{
$campaigns = mysql_query("SELECT * From cms_news WHERE campaign='1'");
while($skriv = mysql_fetch_assoc($campaigns))
{
return
'
<hr/>
<div class="campaign_images">
</div>
<div class="campaign_content">
<b>'.$skriv['title'].'</b><br>
'.$skriv['shortstory'].'
</div>
<p class="gothere">Go there »</p>
<div style="clear:both;"></div>
<hr/>
';
}
}
But the problem with that is return will only give me 1 value then stop the script. How do I solve this? I've heard that I should return an array or something, but how do I do that? thanks. Sorry for my English btw.
As soon as a return statement executes, control leaves the scope of the function. You can only ever return once. It looks like what you want to do is build a string and return the whole thing. So instead of this:
while(condition) {
return value;
}
Do this:
result = '';
while(condition) {
result .= value;
}
return result;
This is a standard pattern for aggregating a result within a function.
Add the data to an array and return that.
$data = array();
while($skriv = mysql_fetch_assoc($campaigns))
{
$data[] =
'
<hr/>
<div class="campaign_images">
</div>
<div class="campaign_content">
<b>'.$skriv['title'].'</b><br>
'.$skriv['shortstory'].'
</div>
<p class="gothere">Go there »</p>
<div style="clear:both;"></div>
<hr/>
';
}
return $data;
If you then just need to output the content then implode and echo:
$data = $obj->getCamps();
echo implode($data);
Although personally I wouldn't add the HTML in the loop. I'd just add the row data to the array and return that:
final public function getCamps()
{
$data = array();
$campaigns = mysql_query("SELECT * From cms_news WHERE campaign='1'");
while($skriv = mysql_fetch_assoc($campaigns))
{
$data[] = $skriv;
}
return $data;
}
And then iterate over the returned array and add the HTML:
<?php foreach ($obj->getCamps() as $camp) { ?>
<hr>
<div class="campaign_images"></div>
<div class="campaign_content">
<b><?php echo $camp['title']; ?></b>
<br>
<?php echo $camp['shortstory']; ?>
</div>
<p class="gothere">Go there »</p>
<div style="clear:both;"></div>
<hr>
<?php } ?>
Just try this:
final public function getCamps()
{
$campaigns = mysql_query("SELECT * From cms_news WHERE campaign='1'");
$data_return = "";
while($skriv = mysql_fetch_assoc($campaigns))
{
$data_return .= //this returns multiple values from your db
'
<hr/>
<div class="campaign_images">
</div>
<div class="campaign_content">
<b>'.$skriv['title'].'</b><br>
'.$skriv['shortstory'].'
</div>
<p class="gothere">Go there »</p>
<div style="clear:both;"></div>
<hr/>
';
}
return($data_return);
}
Hopes this helps.
You can easily return an array with multiple key/value pairs. You just have to know how to use it on the receiving end as well.
return [
'html' => '<hr/><div class="campaing_images>....</div>',
'error' => false,
]
You can also just do a normal array index version
return [
'<hr/><div class="campaing_images>....</div>',
false
]

Categories