I have many articles, divided into sections, stored in a database. Each section consists of a section tag, followed by a header (h2) and a primary div. Some also have subheaders (h3). The raw display looks something like this:
<section id="ecology">
<h2 class="Article">Ecology</h2>
<div class="Article">
<h3 class="Article">Animals</h3>
I'm using the following DOM script to add some classes, ID's and glyphicons:
$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('data-target', '#b' . $i); // set id for section tag
// get div inside each section
foreach($section->getElementsByTagName('h2') as $h2) {
if($h2->getAttribute('class') == 'Article') { // if this div has class maindiv
$h2->setAttribute('id', 'a' . $i); // set id for div tag
}
}
foreach($section->getElementsByTagName('div') as $div) {
if($div->getAttribute('class') == 'Article') { // if this div has class maindiv
$div->setAttribute('id', '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
}
I'd like to modify the above code so that it places certain examples of "inner text" between tags.
For example, consider these headings:
<h3 class="Article">Animals</h3>
<h3 class="Article">Plants</h3>
I would like the DOM to change them to this:
<h3 class="Article"><span class="label label-default">Animals</span></h3>
<h3 class="Article"><span class="label label-default">Plants</span></h3>
I want to do something similar with the h2 tags. I don't yet know the DOM terminology well enough to search for good tutorials - not to mention confusion with DOM programs and jQuery. ;)
I think these are the basic functions I need to focus on, but I don't know how to plug them in:
$text = $data->textContent;
elementNode.textContent=string
Two Notes: 1) I understand I can do this with jQuery (perhaps a lot easier), but I think PHP might be better, as they say some users can have JavaScript disabled. 2) I'm using the class "Article" largely to distinguish elements I want to be styled by PHP DOM. A header with a different class, or no class at all, should not be affected by the DOM script.
I have a site running Typo3.
If I add an element of the type image or textpic, I want the <img>-tag to be surrounded by a couple of divs. So, i thought, i have to use typoscript for that.
So I added:
tt_content {
image.20.wrap = <div class="hello">|</div>
}
I can see it in the object-browser, but it isn't displayed in the frontend. From what i got so far, is, that for image and textpic I have to override this image.20.
Typoscript:
tt_content {
uploads.wrap = <div class="tro-uploads-wrap">|</div>
}
tt_content {
table.wrap = <div class="tro-table-wrap">|</div>
}
tt_content.image.20.imageStdWrap.wrap = <div>|</div>
Adding a wrap around the whole element can be done via:
tt_content.image.20.stdWrap.wrap = <div>|</div>
If you just want to wrap the image it self, use
tt_content.image.20.imageStdWrap.wrap = <div>|</div>
I know this topic was posted everywhere, but their question is not I want. I want to insert some HTML codes before the page is loaded without touching the original code in the page.
Suppose my header was rendered by a function called render_header():
function render_body() {
return "<body>
<div class='container'>
<div class='a'>A</div>
<div class='b'>B</div>
</div>
</body>";
}
From now, I want to insert HTML codes using PHP without editing the render_body(). I want a function that insert some divs to container'div.
render_body();
<?php *//Insert '<div class="c" inside div container* ?>
Just as an alternative using XPath - this should load in the output from render_body() to an XML (DOMDocument) object and create an XPath object to query your HTML so you can easily work out where you want to insert the new HTML.
This will probably only work if you're using XML well formed HTML though.
//read in the document
$xml = new DOMDocument();
$xml->loadHTML(render_body());
//create an XPath query object
$xpath = new DOMXpath($xml);
//create the HTML nodes you want to insert
// using $xml->createElement() ...
//find the node to which you want to attach the new content
$xmlDivClassA = $xpath->query('//body/div[#class="a"]')->item(0);
$xmlDivClassA->appendChild( /* the HTML nodes you've previously created */ );
//output
echo $xml->saveHTML();
Took a little while as I had to refer to the documentation ... too much JQuery lately it's ruining my ability to manipulate the DOM without looking things up :\
The only thing I can think of is to turn on output buffering and then use the DOMDocument class to read in the entire buffer and then make changes to it. It is worth doing some reading of the documentation (http://www.php.net/manual/en/book.dom.php) provided in the script...
ie.:
<?php
function render_body() {
return "<body>
<div class='container'>
<div class='a'>A</div>
<div class='b'>B</div>
</div>
</body>";
}
$dom = new DOMDocument();
$dom->loadHTML(render_body());
// get body tag
$body = $dom->getElementsByTagName('body')->item(0);
// add a new element at the end of the body
$element = $dom->createElement('div', 'My new element at the end!');
$body->appendChild($element);
echo $dom->saveHTML(); // echo what is in the dom
?>
EDIT:
As per CD001's suggestions, I have tested this code and it works.
I'm trying to get the first image with specific class from page by php
<?php
$document = new DOMDocument();
#$document->loadHTML(file_get_contents('http://www.cbsnews.com/8301-501465_162-57471379-501465/first-picture-on-the-internet-turns-20/'));
$lst = $document->getElementsByTagName('img');
for ($i=0; $i<$lst->length; $i++) {
$image = $lst->item($i);
echo $image->attributes->getNamedItem('src')->value, '<br />';
}
?>
this code get all images from the page, i'm trying now to get the images with class "cnet-image" from this page
You should be able to do what you need to with Simple HTML Dom, give it a try, I've used it for several similar things including image crawlers. http://simplehtmldom.sourceforge.net/
It looks like you should be able to use the following for what you need.
// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');
$ret = $html->find('img[class=foo]');
I presume that you want to retrieve the first image with a specific class attribute name in a HTML document.
If that's the case, then this could help.
var l = document.images;
var myclass = "myclass";//This is the class you want
var firstImageWithMyClass = null;
for(var i = 0; i<l; i++)
if(document.images[i].className==myclass){
firstImageWithMyClass = document.images[i];
break;
}
//Then you can see if an image with that class was found,
//then do what you want to do withit here;
if(firstImageWithMyClass!=null){
var imageSource = firstImageWithMyClass.src;
//etc, etc
}
jQuery makes this easier. Let me know if you would like to know how to do the same with jQuery and I can share with you.
I am using CKEditor with PHP.
Using the sample PHP where the $code variable gets echoed printing the code that triggers the CKEditor to show. I do the same only in a real layout and the what happens is the Editor engulfs the surroding HTML inside it as if it was the initialValue for it.
Any idea why I am getting this, please?
Here is the code:
// Include CKEditor class.
#require_once("ckeditor/ckeditor.php");
// Create class instance.
$CKEditor = new CKEditor();
// Do not print the code directly to the browser, return it instead
$CKEditor->returnOutput = true;
// Path to CKEditor directory, ideally instead of relative dir, use an absolute path:
// $CKEditor->basePath = '/ckeditor/'
// If not set, CKEditor will try to detect the correct path.
$CKEditor->basePath = 'ckeditor/';
// Set global configuration (will be used by all instances of CKEditor).
$CKEditor->config['width'] = 600;
// Change default textarea attributes
//$CKEditor->textareaAttributes = array("cols" => 80, "rows" => 10);
//Set formatting options
$config['toolbar'] = array(
array( 'Source','-',
'NewPage','Preview','Templates','-',
'Cut','Copy','Paste','PasteText','PasteFromWord','-',
'Undo','Redo','-',
'Find','Replace','-',
'SelectAll','RemoveFormat','-',
'Maximize', 'ShowBlocks'),
'/',
array('Bold','Italic','Underline','Strike','-',
'Subscript','Superscript','-',
'NumberedList','BulletedList','-',
'Outdent','Indent','Blockquote','-',
'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-',
'Link','Unlink','Anchor','-',
'Image','Flash','Table','HorizontalRule','SpecialChar'
),
'/',
array('Format','Font','FontSize','-',
'TextColor','BGColor')
);
//Set skin
//$config['skin'] = 'kama';//kama si defailt skin for 3.4
//Set language and UI Color
$config['language']='ro';
//$config['uiColor']='#AADC6E';
//Remove the html tags in the status bar (e.g. body p strong for when cursor is in a strong tag within a p tag within the body)
$config['removePlugins']='elementspath';
//Allow / deny resizing of editor from dragging the bottom-right corner. Maximize will still work.
$config['removePlugins']='resize';//Remove resize image
$config['resize_enabled ']=false;//Disallow resizing
//Remove the collapse formatting area button (arrow on the middle-right part of the editor
//$config['toolbarCanCollapse']=false;
// The initial value to be displayed in the editor.
$initialValue = '';
//Add the CKFinder for upload of files directly from the `Add Image` / `Add Flash` buttons.
include_once($CKEditor->basePath.'ckfinder/ckfinder.php');
// You can use the "CKFinder" class to render CKFinder in a page:
$finder = new CKFinder();
$finder->BasePath = 'ckeditor/ckfinder/'; // The path for the installation of CKFinder (default = "/ckfinder/").
//$finder->SetupCKEditor($CKEditor,$CKEditor->basePath.'/ckfinder/');
// Create first instance.
$CKEditorOutput = $CKEditor->editor("continut",$initialValue,$config);
Afterwards, I just do: $output.='<div>'.$CKEditorOutput.'</div>;
Of course, the layout around the div in which the CKEditor resides is larger.
Thank you!
Ah, got it...
This line: $CKEditorOutput = $CKEditor->editor("continut",$initialValue,$config);
The layout contains a div with an ID selector of "continut", so <div id="continut">. Thus messing everything up and turning that div and all inner HTML into the RTE Textarea.
Sorry and thanks everyone!