How to AppendChild and ReplaceChildin PHP Dom? - php

we are working on a project, in which we need to appendChild and ReplaceChild within the PHP DOM, and then save the file.
PHP Code
<?php
$string = '<u>technical/u>';
?>
<html><head></head>
<body>
<div>Stack Overflow is great website for technical professionals.
<p>checking all of the websites</p>
</div>
<h1>Looking something new for a technical professional</h1>
</body>
</html>
we just want to replace $string with duplicated words like "technical" is used in and .
The final HTML code will be
<html><head></head>
<body>
<div>Stack Overflow is great website for <u>technical</u> professionals.
<p>checking all of the websites</p>
</div>
<h1>Looking something new for a <u>technical</u> professional</h1>
</body>
</html>

Related

PHP / HTML: Import HTML file into another one, while merging duplicates

First of all, I know that there are many questions leading towards including HTML.
The thing is, when I include one HTML (1) file into another (2), using <?php include("1.html") ?>, and both files consist of something like this:
<html>
<body>
<div id="specific div">
<span id="span1">1</span>
</div>
</body>
</html>
Having two different spans in the same specific div - once I include one file into the other one, it would look like this:
<html>
<body>
<div id="specific div">
<span id="span1">1</span>
</div>
<div id="specific div">
<span id="span2">2</span>
</div>
</body>
</html>
while I want the contents of the specific div merged into one of them, instead of having to divs with the same id in the end:
<html>
<body>
<div id="specific div">
<span id="span1">1</span>
<span id="span2">2</span>
</div>
</body>
</html>
How do I achieve that?
EDIT: I found a different and less complicated solution for my specific situation. Therefore I can't really select the correct answer now, so I might select one if it gets enough upvotes.
You could use php's DomDocument::loadHTMLFile() function. With this you can load both of your files and merge them the way you like it.
If your file looks like you said, something like this:
<html>
<body>
<div id="specific div1">
<span id="span">bla bla bla</span>
</div>
</body>
</html>
You can use the DomDocument:
$dom1 = new DomDocument();
$dom1->loadHTMLFile("file_1.html", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$dom2 = new DomDocument();
$dom2->loadHTMLFile("file_2.html", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$element = $dom2->getElementById("specific div2")->firstChild;
$dom1->getElementById("specific div1")->appendChild($element);
$merged_html = $dom1->saveHTML()
So this would merge the contents of the div[id="specific div2"] to the div[id="specific div1"]
DOMDocument also supports xpath if you like it more than going through the nodes maually or selecting by id.
If you want to include one html file to another then you can either use iframe or can convert the files to php as well to use include.
Like if you want to include index2.html in index1.html then you can use below iframe code in index1.html:
index1.html
<iframe src="index2.html"></iframe>
Or you can convert your files to PHP and then simply include one file to other like below:
index1.php
<?php include('index2.php'); ?>
You can also use Server Side Include like below to include one html to another:
index1.html
<html>
<body>
<!--#include virtual="/index2.html" -->
</body>
</html>

Assign php code to smarty template engine

I make a new website for my company and i want to use smarty (v3.1.29) for it. Now the problem is that we store the code for all pages in our database (home, products, downloads, ...). Some pages contains PHP inline functions like:
<?php include("functions.php"); ?>
<p> Hello <?php echo printWorldInColor(); ?> </p>
In my template (.tpl) file I have a div-section to load the content from our database:
<html>
<body>
<div id="content">
{$content}
</div>
</body>
</html>
So my code looks like this afterwards:
<html>
<body>
<div id="content">
<?php include("functions.php"); ?>
<p> Hello <?php echo printWorldInColor(); ?> </p>
</div>
</body>
</html>
Is there a way that smarty processes the PHP-code before parsing it?
Hint: I dont want to edit my template file. I just want to parse the database content to my content-section of the website.
What i tried:
saved database-content into a string and replaced PHP-tags with smarty-PHP-tags, then assign it to the template
SmartyBC-Class
You can't do that in Smarty. Also running php code stored in the database sounds like a terrible idea. But if for some reason you have to go on with this nonsense (and considering that you can't use eval), you can try this:
Read the php code from the database.
Save to a temporal php file
Turn on output buffering with ob_start()
include the file you have created
assign the output to a variable with ob_get_clean()
assign the variable to the template
But if I was you, I would try to do the project in another way.

Are there any more Unobtrusive Server-side Scripts like hQuery for easier templating?

I came across this interesting templating tool, what the author calls as hQuery which is an 'Unobtrusive Server-side Scripting'. [More information here - https://github.com/choonkeat/hquery ]. It is built in Ruby for the RoR platform.
I wanted to know if something similar is available for other platforms (PHP, Python, Java)
PS : I know about templating engines like smarty and twig. I'm looking for something closer to hQuery.
Not that I know of, but I have been doing something similar in concept, although a lot more simple, in PHP using phpQyery and some custom html-like markup.
For instance, here is a simplified non-standard html chunk:
<bodynode>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<div class="holder">
<article>
<header class="col_12f">
<component id="logo"></component>
<component id="address"></component>
<component id="languages"></component>
<component id="mainmenu"></component>
</header>
<section id="banner">
<component id="maingallery"></component>
<component id='sideMenu'></component>
</section>
<section class="col6 first" id="intro_title">
<h1 class="underlined"></h1>
<section class="col3 first" id="intro_col1"></section>
<section class="col3 last" id="intro_col2"></section>
</section>
<section class="col3" id="location"></section>
<section class="col3 last" id="services"></section>
</article>
<div class="clear"></div>
</div>
<component id="footer"></component>
</bodynode>
Using phpQuery, which works server-side with XML and HTML Dom Nodes, in a way very similar to jQuery, I map all tags with content coming from the db, using their ID as key. as well as all <component></component> tags with custom output from functions. So the existence of a <component id="logo"></component> would cause the call of a function called component_logo, using:
function replaceComponents ($pqInput){
$pqDoc = phpQuery::newDocument($pqInput);
$comps = pq('component');
foreach ($comps as $comp){
$compFunc = 'component_'.pq($comp)->attr('id');
pq($comp)->replaceWith($compFunc($comp));
}
return $pqDoc;
}
and
function component_logo($comp){
$pqComp = phpQuery::newDocument(file_get_contents('Templates/Components/logo.component.html'));
$pqComp->find('a')->attr('href','/'.currentLanguage().'/')->attr('title','Website Title');
$pqComp->find('img')->attr('src','/Gfx/logo.png');
return $pqComp;
}
Although it's not based on a MVC pattern and uses straight procedural programming, so far this method has allowed for a very quick development of small to medium sized sites, while keeping things nicely DRY.
I don't like using other templating engines much, really because I find them a little to heavyweight for anything I actually want to do (smarty for example).
There is a school of thinking that would say: PHP is already a templating engine... why build templates within templates?
I do disagree with this to an extent, I find templating very useful in abstracting HTML from PHP code.
Below is an edited method from my templating class that I use that will explain how easy it is to actually make yourself.
$params = array("<!--[CONTENT]-->" => "This is some content!");
$path = "htmltemplates/index.html";
$html = implode("",file($path));
foreach($params as $field => $value) {
$html = str_ireplace($field, $value, $html);
}
echo $html;
There is quite a bit more meat around this, but this is the core code. Read a file into an array, implode, search through the $params array and replace $field with $value in $html. Output the edited $html.
your index.html file will look something like:
<html>
<head>
<title>This is a template</title>
</head>
<body>
<div id="page-container">
<!--[CONTENT]-->
</div>
</body>
</html>
Your output will be:
<div id="page-container">
This is some page content!
</div>
Maybe look at implementing your own templating engine! :)

How can I make a php script add a tab to every line of an include file?

Within my HTML, I have a php script that includes a file. At that point, the code is indented 2 tabs. What I would like to do is make the php script add two tabs to each line. Here's an example:
Main page:
<body>
<div>
<?php include("test.inc"); ?>
</div>
</body>
And "test.inc":
<p>This is a test</p>
<div>
<p>This is a nested test</p>
<div>
<p>This is an more nested test</p>
</div>
</div>
What I get:
<body>
<div>
<p>This is a test</p>
<div>
<p>This is a nested test</p>
<div>
<p>This is an more nested test</p>
</div>
</div>
</div>
</body>
What I want:
<body>
<div>
<p>This is a test</p>
<div>
<p>This is a nested test</p>
<div>
<p>This is an more nested test</p>
</div>
</div>
</div>
</body>
I realise I could just add leading tabs to the include file. However, VS keeps removing those when I format the document.
In your test.inc file, you can use output buffering to capture all the output of the PHP script, before it is sent to the browser. You can then post-process it to add the tabs you want, and send it on. At the top on the file, add
<?php
ob_start();
?>
At the end, add
<?php
$result = ob_get_contents();
ob_end_clean();
print str_replace("\t" . $result, "\n", "\n\t");
?>
I don't necessarily subscribe to this solution - it can be memory intensive, depending on your output, and will prevent your include file from sending partial results to the client as it works. You might be better off reformatting the output, or using some form of custom "print" wrapper that tabs things (and use printing of heredocs for constant HTML output).
Edit: Use str_replace, as suggested by comment
I don't think your solution can be done easily. You might consider using HTML Tidy to clean your source code before presenting it to a client. There are good tutorials for it on the internet.
The easiest solution is to add leading tabs to the include file, but instead of using literal tabs, use the \t escape sequence.

Cheap php templating with vprintf?

Ok,
so printf/sprint/vprintf all accept a certain type specifier syntax %[num][type]. (http://us2.php.net/sprintf see examples 3 and 4) Where num is the index to the type.
Example:
vprintf('Number %1$d string %2$s. String %2$s, number %1$d',array(1,"no"));
Yes, it is limited... And you would need to maintain the indexes. But it's native to the language and (i think) fast.
I just want some thoughts on how useful this would be as say a second stage to something like this: http://www.techfounder.net/2008/11/18/oo-php-templating/.
(and if anyone knows about printf/vprintf's speed that would be appreciated)
full example of what i'm talking about:
frontpage.php:
<html>
<head>
<title> %1$s </title>
</head>
<body>
Hello %2$s! You have reached page: %1$s!
</body>
</html>
whatever.php:
ob_start();
include frontpage.php;
$ob_output = ob_get_clean();
vprintf($ob_output,"Page Title","Bob");
If you want cheap PHP templating, use separate files with PHP expression blocks. It is possible to make a templating system using printf-style format strings, but there are two main problems I can see with this approach: speed and readability. The printf functions are intended for use on shorter strings, and although I don't have any statistics on hand, I think it's safe to say that running a sprintf() or a vprintf() on one huge string representing the page body will be slower than just using PHP expression blocks in a file.
That leads into the next issue: readability. Compare these two HTML templates:
<html>
<head>
<title>%s</title>
</head>
<body>
<div id="main">
<h1>%s</h1>
<p>%s</p>
</div>
<div id="other">
<p>%s</p>
</div>
<p id="footer">
%s. Took %.2f seconds to generate.
</p>
</body>
</html>
and
<html>
<head>
<title><?= $title ?></title>
</head>
<body>
<div id="main">
<h1><?= $header ?></h1>
<p><?= $body_text ?></p>
</div>
<div id="other">
<p><?= $misc_info ?></p>
</div>
<p id="footer">
<?= $copyright ?>. Took <?= $load_time ?> seconds to generate.
</p>
</body>
</html>
Or, let's say I had decided to use format strings with indexed arguments. Say, something like this:
<h1>%1$s</h1>
<p>%2$s</p>
<span id="blah">%3$s</p>
<p>%4$s</p>
<p>%5$s</p>
Now, what if I wanted to switch the ordering around?
<h1>%1$s</h1>
<p>%3$s</p>
<span id="blah">%5$s</p>
<p>%4$s</p>
<p>%2$s</p>
These are obviously contrived, but think about how it would be to maintain the printf templates in the long run.
So, in general, if you want quick-and-dirty PHP templating, use template files that contain PHP expression blocks. The printf functions are a lot better at tackling smaller string formatting tasks.
I generally have two files:
A controller of some sort (recipes.controller.php rewritten to /recipes/123)
One of many views for a controller (recipes.view.html)
I simply do all of the logic/database work within the controller and then include the appropriate view at the end. The view has access to all of the variables in the controller so I already have things like $title, $ingredients[], etc. created. I'm not really sure why people make it any more complicated than that. It's very easy to follow.
The view file will basically just look like this:
<html>
<head>
<title><?=$title ?></title>
</head>
etc...
Rasmus Lerdorf, creator of PHP, prefers to include his variables something like this:
<select class="f" name="cat" id="f_cat" size="1">
<option selected>Category</option>
<?php foreach($categories as $cat) echo <<<EOB
<option value="{$cat}">{$cat}</option>
EOB;
?>
For reference, <<<EOB through EOB; is a heredoc.
Source: The no-framework PHP MVC Framework by Rasmus Lerdorf

Categories