Maintain html code clean and independent from server side code

Hi,

If I have an html code, I want to insert dynamically the php code but I want to maintain clean the html code. For example:
If I have the html code:

<a href='#'>Link</a>

Usually the way to proceed to insert dynamically the url is to put a php variable instead of #, editing the html file :

<a href='<?php echo $url_here ?>'>Link</a>

but doing so, I go to dirty the html code, but I do want maintain it clean and independent.

I am wondering if exists something to insert dynamically that php code without edit the html file, something that it is able to comprehend the following:

  • I want to put the content of the php variable $url_here as value of the attribute href of the anchor that has inside the particular text “Link” -

I know it is a weird question. Is it science fiction or does really exist anything like that? Please, what do you think about it? Many thanks!

Absolutely! :-) What you want is a template engine; check out twig for example, the default engine of Symfony.

Keeping in mind that “clean” is very subjective, there are several basic alternatives.

The first one is to use a template engine such as twig: http://twig.sensiolabs.org/

<a href="{$url_here}">Link</a>

A second one is to use the heredoc notation: http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

$a = <<<EOT
<a href="{$url_here}">Link</a>
EOT;
echo $a;

No templating engine required but heredoc does not seem to be very popular.

Mind you, it’s not nearly as powerful as a template engine – it’s just interpolated strings, basically the same as using double quotes. If you want loops and conditions, you’ll still end up with hopelessly tangled spaghetti code. A template engine is the way to go IMHO, as it makes for SoC to the greatest possible extent by abstracting away the PHP logic itself.

Tell that to the react javascript people.

As always, it depends. I have used twig quite extensively but often find myself bogged down with loops and conditions. On the other hand, php is rather good with loops and conditions. For example:

True. ^^

Ok Thanks!
But in all of those solutions you gave, I have to edit my html file! Is there exists anything of less obtrusive?

Yes, but it would be more resource intensive.

If the HTML did not have PHP variables in it, nor placeholders in a HTML template, the DOM would need to be parsed, the PHP values inserted into it, and then output.

Well I wouldn’t consider this obtrusive as compared to

<a href='<?php echo $url_here ?>'>Link</a>

AFAIK there’s no ready-made solution for directly binding an attribute value to a variable based on the text content of that element, so you’d have to write your own parser/engine for this rather specific task.

Now if you want to dynamically replace the href attribute (say) based on the text content, you might use JS for this, like e.g.

var links = document.querySelectorAll('a');

// Iterate over the anchor elements
[].slice.call(links).forEach(function(link) {

  // Set the href value based on the text content
  switch (link.textContent.trim()) {

    case 'Link':
      link.href = '#foo';
      break;

    case 'Other link':
      link.href = '#bar';
      break;
  }
});

But this is hardly a proper way to render a page when you can serve it with the correct values in the first place, i.e. using PHP. If you’re using heredoc as @ahundiak suggested, all you have to do is replace those values with the corresponding PHP variables.

x-post

1 Like

I’m curious, please can you give me any example?

You would want to load from a file instead of a string and the variable values from a database or elsewhere. .
And no doubt the DOM would be more complex making this approach a maintenance nightmare.
But if you would rather hack PHP files than your HTML files this is a good place in the documention to start.
http://php.net/manual/en/class.domdocument.php

<?php
$html = <<<HTML
<html>
<head>
<title></title>
</head>
<body>
<h1></h1>
<div></div>
</body></html>
HTML;

$title_heading = "Simple Example";
$div_text = "Just some text to put into the div";

$doc = new DOMDocument();
$doc->loadHTML($html);

$doc_title = $doc->getElementsByTagName('title');
$doc_h1 = $doc->getElementsByTagName('h1');
$doc_div = $doc->getElementsByTagName('div');

$doc_title[0]->nodeValue = $title_heading;
$doc_h1[0]->nodeValue = $title_heading;
$doc_div[0]->nodeValue = $div_text;

echo $doc->saveHTML();
?>
1 Like

A quick and dirty way would be using regular expressions, like

// The file to parse
$html = file_get_contents('index.html');

// Map text content to href values
$replacements = [
  'Link'       => '#foo',
  'Other link' => '#bar'
];

// Iterate over the replacements
foreach ($replacements as $text => $replacement) {

  // If a matching anchor element was found,
  // replace its href attribute accordingly
  $html = preg_replace_callback(

    "/<a.*>{$text}<\/a>/", 

    function($matches) use ($replacement) {
      return str_replace('#', $replacement, $matches[0]);
    }, 

    $html
  );
}

// Output the result
echo $html;

But do you really want to go to that bother, only to avoid touching the HTML?

(x-post again w/ @Mittineague’s much cleaner suggestion.) ^^

1 Like

I recently had a similar situation where a PHP Framework was unable to save AmpProject HTML content. This was solved by inserting ob_start(); before the content. After </html> saving the content to a cached .html file.

The .htaccess file checks to see if the REQUEST_URI existed and rendered the cached file otherwise fall through, call index.php, MySQL, PHP, Framework, process then output view.

Edit:
Your “clean” code will be stored in the cached file.

1 Like

Is it science fiction

It’s rather a pulp fiction, as there is no Artificial intelligence yet. So, there is no code that can read your mind and place some variable wherever you wish to.

It’s you who have to mark the spot.

You have to understand that there are many different places where you want to output different variables. And for this purpose you definitely have to name them. Leaving you no choice but calling certain names in your HTML instead of just anonymous # marks.

There are many different syntaxes but the meaning is essentially the same: output some variable here. An easies one is similar to what you have at the moment but way shorter:

<a href='<?= $url_here ?>'>Link</a>

in your place I’d stick to this one for a while.

Trust me, the syntax for the variable output is your least concern. what you should think of is control structures. In any HTML template there are always loops and conditional statements, which syntax is far more sophisticated than a silly variable output. So, that’s a way more important thing to consider.

For example, the links are often go in numbers. And therefore you usually have not one link but an array of data that you wan to format as hyper-links in HTML. Consider this code:

<div class="link-list">
    <ul>
        <?php foreach ($links as $row): ?>
            <li><a href="<?=$row['link']"><?=$row['name']</a></li>
        <?php endforeach ?>
    </ul>
</div>

this kind of approach is considered the best so far in keeping HTML as clean as possible, while having dynamical data output.

in case you prefer Twig, it won’t be essentially different:

<div class="link-list">
    <ul>
        {% for row in links %}
            <li><a href="{{row.link}}">{{row.name}}</a></li>
        {% endfor %)
    </ul>
</div>

Note that all the control structures are in place, while differ only in syntax.

You see, the independence is a myth, a delusion. You cannot have your HTML template to be independent from the presentation logic. There is always one. So, this way or another but you have to “pollute” your nice and clean HTML with control structures. The sooner you realize that, the less time you’ll waste.

No offense, but all other answers (save ones mention twig) are but empty musings, inapplicable for the any real life application.

4 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.