I am currently trying to place something like this https://shortdomain.com/api?p=a-href-url-here.com before every link on my website in a specific div.
$main = get_the_content_with_formatting();
$stripped = str_replace('<a href="http://example.net/', '<a href="https://shortdomain.com/api?p=http://example.net/', $main);
The method above works, but only when the link is that URL, and with any other it obviously will just return the standard URL.
Is there a way that I can prefix my desired link to each href using JavaScript, or PHP?
Here's the selector of the contents inside of $main
#the-post > div.post-inner > div.entry > p > strong > a
Don't ever make the mistake of parsing HTML like text; it's not! Use a proper DOM parser to extract your values and then alter them.
<?php
$main = "<div><p>Here is some <a href='http://example.com/'>sample</a> text.</p></div>";
$dom = new DomDocument();
$dom->loadHtml($main, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
foreach ($dom->getElementsByTagName("a") as $anchor) {
$href = $anchor->getAttribute("href");
if ($href) {
$anchor->setAttribute("href", "https://shortdomain.com/api?p=" . urlencode($href));
}
}
echo $dom->saveHTML();
This is a good task for PHP's built-in DOMDocument and DOMXpath classes. Using xpath ensures that you only change anchors inside the div that you want.
$main = '<div class="post-inner"><div class="entry"><p><strong>link</strong></p></div></div>';
$doc = new DOMDocument();
$doc->loadHTML($main, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXpath($doc);
$anchors = $xpath->query('//div[contains(#class, "post-inner")]//a');
foreach ($anchors as $a) {
$a->setAttribute('href', 'https://shortdomain.com/api?p=' . $a->attributes->getNamedItem('href')->nodeValue);
}
echo $doc->saveHTML();
Output:
<div class="post-inner"><div class="entry"><p><strong>
link
</strong></p></div></div>
Demo on 3v4l.org
You can use the attribute selector with jquery to match all desired elements and then use the method 'attr' to change the href attribute.
$("#the-post > div.post-inner > div.entry > p > strong > a[href=\"http://example.net/\"]")
.attr("href", "https://shortdomain.com/api?p=http://example.net/");
I didn't really test it, but it should work just fine.
If you are doing this client-side, it's pretty painless with javascript's querySelectorAll:
let as = document.querySelectorAll('#the-post .post-inner .entry p strong a')
as.forEach(a => a.href ="https://shortdomain.com/api?p="+a.href)
Don't change
<div id="the-post">
<div class="post-inner">
<div class="entry">
<p>
change these:
<strong>
some inside <br />
some other inside
</strong></p>
</div>
</div>
</div>
Get rid of the dummy website then.
$main = get_the_content_with_formatting();
$stripped = str_replace('href="', 'href="https://shortdomain.com/api?p=', $main);
Related
This question already has answers here:
Hiding a Div using php
(6 answers)
Closed 1 year ago.
I want to show and hide a div based on a condition. This time I am not using any function since I thought it would be better as simple as possible.
I am trying to show and hide 2 DIVs based on a "status" of the user ($new). I don't know if it's possible to assign a PHP value to a JavaScript variable and the best way to do it ...
"var" is supposed to get the value of "$new".
Javascript:
<script>
var var = $new;
if (var != 1) {
document.getElementById("subjectr").style.display = "block";
} else {
document.getElementById("subjectr").style.display = "none";
}
</script>
HTML:
<center>
<div id="subjectr" value="<?php echo "$new"?>" style="display: none">
COORDINADOR
</div>
</center>
If you know a better way to do it, I would appreciate your help.
You don't need JS, simply echo or wrap the desired HTML into an if $new is true right on the server-side
Using PHP
<?php if ($new) { ?>
<div>Content for new users</div>
<?php } ?>
Using CSS (and PHP)
<div class="<?= $new ? '' : 'isHidden' ?>">Content for new users</div>
.isHidden { display: none; } /* Add this class to CSS file */
The above might come handy if at some point, by using JavaScript you want to toggle the visibility of such element using .classList.toggle('isHidden') or jQuery's .toggleClass('isHidden')
Using JavaScript (and PHP)
If you really want to pass your PHP variable to JavaScript:
<div id="subjectr">Content for new users</div>
<script>
var isNew = <?php echo json_encode($new); ?>;
document.getElementById("subjectr").style.display = isNew ? "block" : "none";
</script>
<!-- The above goes right before the closing </body> tag. -->
PS:
The <center> tag might work in some browsers but it's long time obsolete. Use CSS instead.
The value is an invalid HTML5 attribute for div Element. Use data-value instead.
What's doing the method=POST; on an <a> tag?
var var is a syntax Error in JavaScript, var being a reserved word. Use a more descriptive var isNew instead.
Instead of using javascript, you could use PHP to influence the display style of your div by using a ternary to decide whether it is none or block:
<center>
<div id="subjectr" value="<?=$new?>" style="display: <?=$new != 1 ? 'block' : 'none'?>">
COORDINADOR
</div>
</center>
For first, you should avoid to use var as a variable in your JS code, since it's an reserved key.
For your problem, revise your JS code:
<script>
var cond = document.getElementById('subjectr').getAttribute('value');
if (cond != 1) {
document.getElementById("subjectr").style.display = "block";
}
else {
document.getElementById("subjectr").style.display = "none";
}
</script>
You can get attribute result using getAttribute method in javascript, or attr method in jQuery.
A javascript variable can get the value of a PHP variable like so (assuming the PHP var is an integer):
var myvar = <?=$new?>;
Since you tag this as a PHP and a CSS issue, I think our mobile function is pretty near. This is our CSS "shownot" class:
.shownot { display: none !important; }
After, we use to hide certain cols on device mobiles, in your case the "$new" var:
<?php
$new = isMobile() ? 'shownot' : '' ;
?>
Finally, use as class whenever you need
<div id="subjectr" class="<?php echo $new;?>">
COORDINADOR
</div>
Not sure this is possible but maybe you can help.
I have a list, where the content of the <li>'s is generated by Javascript, through a function called showLink(); this function is on another server and it's not controlled by me.
The showLink(); function generates a html link. I am interested in the generated anchor text.
QUESTION: Is there a way I can use Jquery to get the anchor text of that link into a Jquery variable?
Here is the code:
<ul class="my_list">
<? $zero = '0';
for($rn = 1; $rn <= $traffic_rows_nr; $rn++){ ?>
<li><script language="JavaScript">showLink(<? echo $rn; ?>)</script></li>
<? } ?>
</ul>
Thank you!
Something like
var anchorText = $("ul.my_list li a").text();
or...
var anchorText = [];
$("ul.my_list li a").each(function() {
anchorText.push($(this).text());
})
// anchorText is now an array of the text in all the anchors in the list
var text = $(".my_list a").text(); Should do it
$html = $("<!-- comment --> <p>text</p>");
creates a jQuery collection like so
$( [the comment], [text node], p )
How can I access the paragraph only? .find("p") returns an empty collection
And, for extra points,
$html = $("<p>text</p>");
creates a jQuery collection like so
$( p )
Is there a fail safe way to get at the p, and only the p, that works whether the comment is there or not?
The simplest way is with filter and the universal selector *, which matches all elements.
$html = $("<!-- comment --> <p>text</p>").filter('*');
var p = $html.filter(function() { return this.nodeType === 1; });
jsFiddle.
Try this demo. Maybe this is not exactly how you're gonna use it, but you get the point.
<div class="text">
<!-- comment -->
<p>text</p>
</div>
var html = $('.text').html();
html = $.trim(html.replace(/<!--(.*?)-->/ig, ''));
alert(html);
One way is to get by index like in $html = $("<!-- comment --> <p>text</p>"); you can get p tag using $($html[2]).
OR
$html = $("<!-- comment --> <p>text</p>");
$target = new Object();
for(key in $html){
if(typeof $html[key] === 'object' && $html[key].localName === 'p')
$target = $html[key];
}
I have a vague idea on howto do this but I hoped more experienced devs might have a simpler solution.
I have a sting of HTML code from a JSON feed and where an "a" tag exists with an images inside the "a" tag I want to modify and add attributes. example:
<a style="color:000;" href="images/image.jpg">
<img width="100" height="20" src="images/image_thumb.jpg" />
</a>
I would like to change it to be:
<a style="color:000;" href="images/image.jpg" rel="lightbox" >
<img width="100" height="20" decoy="images/image_thumb.jpg" />
</a>
So adding an attribute to the "a" tag and modifying an attribute in the "img" tag. There maybe multiple links within the HTML code some with and without images and other HTML code surrounding them.
To be clear this is NOT modifying HTML already rendered on the page, this is modifying a string of code before it gets rendered.
To be extremely clear here is the JSON feed in question: http://nicekiwi.blogspot.com/feeds/posts/default?alt=json
The HTML code that contains the tags are found at "feed > entry > content > $t"
Am currently working with Mootools 1.3
Any ideas? Thanks.
First, put it in a new element that does not exist on the page, then modify it as usual:
var container = new Element("div", { html: yourHTML });
container.getElements("a img").forEach(function(img){
var link = img.getParent("a");
img.decoy = img.src;
img.removeAttribute("src");
link.rel = "lightbox";
});
Demo here: http://jsfiddle.net/XDacQ/1/
In straight JS
var a = document.createElement('div');
// put your content in the innerHTML like so
a.innerHTML = '<a style="color:000;" href="images/image.jpg"><img width="100" height="20" src="images/image_thumb.jpg" /></a>';
var b = a.firstChild;
b.rel = 'lightbox';
var c = b.firstChild;
c.setAttribute('decoy', c.src);
c.src = null;
// now you have your a tag
var newA = a.innerHTML;
Dumbest regexp
var string = '<a style="color:000;" href="images/image.jpg">="images/image_thumb.jpg" /></a>',
text = '';
text = string.replace('href', 'rel="lightbox" href');
text = text.replace('src', 'decoy');
Is it possible to generate comments for closing div tags, lets take this ex. into consideration normal HTML:
<div id="content">
...
...buch of html or whateve
</div>
with comments :
<div id="content">
...
...buch of html or whateve
</div><!--End of content-->
and so on go trough each div element and comment the end of it ?
Here is a possible solution, in PHP, using DOM :
Using PHP allows you to save it, or whatever you need to ; and as it's using DOM, which is quite standardized, translating this to another language shouldn't require too much work.
(And, judging from a comment on your question, you didn't exclude other languages that JS)
$html = <<<HTML
<div id="content">
...
...buch of html or whateve
</div>
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$divs = $dom->getElementsByTagName('div');
for ($i = $divs->length - 1 ; $i > -1 ; $i--) {
$div = $divs->item($i);
if ($div->hasAttribute('id')) {
$id = $div->getAttribute('id');
$comment = $dom->createComment("End of {$id}");
if($div->nextSibling) {
$div->parentNode->insertBefore($comment, $div->nextSibling);
} else {
$div->parentNode->appendChild($comment);
}
}
}
echo $dom->saveHTML();
Which gets you the following HTML source :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<div id="content">
...
...buch of html or whateve
</div>
<!--End of content-->
</body></html>
A couple of things to note :
DOM allows one to load and parse non-valid HTML
And generates valid-HTML
And, about what this does :
Load the HTMl string, using DOMDocument
Search for all <div> tags
Foreach <div> tag :
If it has an id attributes,
Get its value
Create a comment based on that value
And add it to the DOM, after the </div> tag
Another solution, thinking about it, would probably have been to use XPath, instead of getElementsByTagName + hasAttribute...
using jQuery, this is very simple.
jQuery('div').after('<!--end of content-->');
EDIT:
jQuery('div').each(function(){ jQuery(this).after('<!-- end of '+jQuery(this).id + '-->');});
var divs = document.getElementsByTagName("div");
for (var d = divs.length-1; d >= 0; --d) {
var div = divs[d];
var id = div.id; // d.getAttribute("id")
if (id) {
var cmt = document.createComment("End of " + id);
div.parentNode.insertBefore(cmt, div.nextSibling);
}
}