joe_g

<? and PHP7 and template syntax opinion needed

Recommended Posts

Hi everyone,

I just wanted to see what your opinions were on this matter.

I'm a big fan of php's template syntax:

<?foreach():?>
<?endforeach?>

It produces nice HTML highlighting. I've notices that some hosting companies removing the support for short tags while upgrading to PHP 7.  This makes the template syntax a lot less attractive. What do you use? Am I stuck in the past? Should I just use twig?

thank you,

j

 

Share this post


Link to post
Share on other sites

Just use `<?php foreach(): ?>` and `<?php endforeach; ?>` - I very much doubt hosting companies will remove support for that. I wouldn't bother using a Template Language. It's just overhead that's not often worth it. 

  • Like 7

Share this post


Link to post
Share on other sites

Agreed.

In template files I personally prefer <?php foreach (): ?> ... <?php endforeach; ?> (and similar syntax for if...endif etc.) and for output the short echo syntax (<?= $some_var ?>) makes sense, but I'd also advice against using short opening tags (<? ... ?>). Although it remains a part of PHP syntax, there's no guarantee that it's always going to be enabled, and it's commonly frowned upon by PHP devs 🙂

  • Like 4

Share this post


Link to post
Share on other sites
10 hours ago, LostKobrakai said:

Since php 5.4.0 short tags are always enabled, so that's not really a problem anymore, and really in template-files using them just removes a lot of unnecessary extra syntax. Just don't use them anywhere else.

You're talking about short echo tags (<?= ... ?>) right? In that regard I agree: that's a good solution in template use.

Short open tags (<? ... ?>) are a different thing entirely, and although earlier decision to remove them was apparently cancelled, they're still discouraged and disabled by default.

  • Like 2

Share this post


Link to post
Share on other sites

Ah yeah, I'm not doing much PHP anymore, so missed the difference. Short opening tags I'd not use as well.

Share this post


Link to post
Share on other sites
Quote

It produces nice HTML highlighting

Did you mean CODE highlighting in your editer e.g. for php ?

Why all the fuzz about <?foreach():?>   <?endforeach?>

I use

<?php
.... your code ;
....... ;
?>

It gives me all the php code highlighting in my editor and it simply works everywhere

 

Share this post


Link to post
Share on other sites

@pwired, it's just about separation of concerns (code and markup), and honestly it's also largely about looks: if there are multiline PHP code blocks within your template files, it appears that you're mixing code with markup, which is generally discouraged.

In contrast, by using only the short syntax of certain statements (such as <?php foreach (): ?> .. <?php endforeach; ?>) or short echo statements (<?= $variable ?>) you're making it as obvious as possible that you're using PHP as a templating language and indeed not entangling business logic with markup.

 

  • Like 2

Share this post


Link to post
Share on other sites

Hi teppo

I am not sure what you are referring to. As far as I can see it (yet?) one of the beauties of Processwire is the possibility of making api calls and using php directly in your html. Isn't that already using PHP as a templating language ? So when doing that, where is at all the difference between using PHP as a templating language and entangling business logic with markup ?

Share this post


Link to post
Share on other sites

Hey @pwired

The point is that when you do this ...

<ul>
    <?php foreach ($pages->find("template=news-item, limit=5, sort=created") as $item): ?>
        <li><a href="<?= $item->url ?>"><?= $item->title ?></a></li>
    <?php endforeach; ?>
</ul>

... it looks a bit cleaner (as in "less like code mixed with markup") than doing something like this:

<ul>
    <?php
    foreach ($pages->find("template=news-item, limit=5, sort=created") as $item) {
        echo "<li><a href='" . $item->url . "'>" . $item->title . "</a></li>";
    }
    ?>
</ul>

... or this:

<ul>
    <?php
    foreach ($pages->find("template=news-item, limit=5, sort=created") as $item) {
    ?>
        <li><a href="<?php echo $item->url; ?>"><?php echo $item->title; ?></a></li>
    <?php
    }
    ?>
</ul>

I wouldn't say that there's anything wrong with using selectors within template files, although personally I try to avoid even that when possible. What we're discussing here is simply the syntax used in template files: if you use "full-blown", especially multiline <?php ... ?> code blocks it can seem like you're mixing view side (markup) with business logic (code) even if you're not.

On the other hand (probably not what you meant, but just to clarify) if you're wondering why business logic and markup should be separated in the first place, there are a number of reasons to do that. In my case the biggest benefits are a) the ability to alter data structure (model), business logic, or representation (markup) without touching other parts of the site or app, and b) the ability to switch entire view – or use multiple views simultaneously – without having to duplicate any actual "code".

(There's a sh*tload of stuff about this in the web, so I won't go into too much detail here. Just google "separation of concerns".)

---

Slightly off-topic, but regarding selector use within markup, and why I personally prefer to avoid that: this is in part because in my opinion it looks cleaner, but also because this way I can tweak template names, data structures, etc. without having to modify my views at all. This in turn becomes more useful when you have multiple views for the same data. So, once again, "depends on the use case" 🙂

  • Like 5

Share this post


Link to post
Share on other sites

Hi, Teppo

Thanks for this clarification and showing these examples. You even have it explained better than
what I read in most stackoverflow post. I have saved your post in my Design patterns folder.

I see now there is more than just <?php ......?> You are right it makes things better readable
and separatable. Maybe it also makes it less load for memory ?

I just checked if my code editer is capable of highlighting this style of php syntax,
and yes it highlights this style of php code nicely where it should 🙂

All good, thanks.

  • Like 2

Share this post


Link to post
Share on other sites

 

If I understand it right then the delayed output strategy in processwire is best suited for separating business logic from view markup.

business logic goes in the template files and view markup goes in _main.php

I like the way of building up view markup in a variable e.g. $content with the .= operator

and if you follow the wire render pattern way of camilo castro you can have many view files

 

 

 

 

Share this post


Link to post
Share on other sites

I'm currently doing this. But it makes my eyes bleeeeed. On top of that, sublime can't handle the tabulation properly with this syntax 😮

    <div class="projects">
        <?php foreach($projects as $project):?>
            <div class="project">
                <?php if($project->iconimage):?>
                    <?php
                        $thumb = $project->iconimage->size(800,800,['upscaling'=>false, 'cropping'=>false]);
                    ?>
                    <img src="<?=$thumb->url?>">
                <?php else:?>
                    <?php
                        $total = count($pages->get('/missingimages')->missingimages);
                    ?>
                    <img src="<?=$thumb->url?>">
                <?php endif;?>
            </div>
        <?php endforeach;?>
    </div>

 

Share this post


Link to post
Share on other sites

I don't understand your code

$total is never used and $thumb is not defined if you don't have an iconimage...

Maybe something like this?

<div class="projects">
  <?php foreach($projects as $project):
    $imgOrCount = '';

    if($project->iconimage) {
      $imgOrCount = '<img src="'.
        $project->iconimage->size(800,800,['upscaling'=>false, 'cropping'=>false]).
        '">';
    }
    else {
      $imgOrCount = count($pages->get('/missingimages')->missingimages);
    }
    ?>
    <div class="project">
        <?= $imgOrCount ?>
    </div>
  <?php endforeach;?>
</div>

 

Share this post


Link to post
Share on other sites

Yes, it's not finished. My point is the syntax. I'm looking for a way to avoid having html inside php. In other words avoid this

$imgOrCount = '<img src="'.
  $project->iconimage->size(800,800,['upscaling'=>false, 'cropping'=>false]).
  '">';

for me personally, this way of writing makes it a bit harder to spot errors (like forgetting a ", or similar).

It's just that <?php foreach($projects as $project):?> is a lot less readable than <?foreach($projects as $project):?> if you write a lot of this type of statements

Share this post


Link to post
Share on other sites

Sounds like you want to use a "real" template system 😉 

 

  • Like 1

Share this post


Link to post
Share on other sites

Got to agree: there are a number of ways to get past this, but I'd argue that it's less about the syntax itself, and more about the way you structure your templates.

In my case (and yes, this is a shameless plug) I'm using pw-mvc so that I can move anything I see as "code" to a separate controller file, and only include simplest loops and output statements on the view side. Sure, this project doesn't force any such restraints, but as a general rule of thumb I try to make my views as "dumb" as possible: as long as they have absolutely no idea how variables they output are generated, they a) remain clean and b) I can easily modify just the view, or just the controller.

One way to handle structures that need a bit of pre-processing is to loop through $projects twice: once in the controller, where you store just the required fields (formatted to your liking) in an array, which you then pass to the view, where you iterate over it second time. Two loops is not optimal in terms of performance, but typically the performance hit is questionable at best, and this approach can make your view files much cleaner.

Another approach I like to implement are separate render-functions: renderThumb(), renderNewsBlock(), renderHighlight(), etc. Depending on the project I often include a common functions.php file with these functions somewhere before markup is generated, and then abstract any complex, repeatable stuff there. Sure, that way you're kind of mixing HTML with code as well (in functions.php), but your views remain nice and clean 🙂

Share this post


Link to post
Share on other sites

Yeah, I can see how things leans towards twig and similar. What I run into with twig and the likes is lots of small annoying exceptions: Like, I have to do something with the second last item in a list, for example. My sites are usually quite simple, mostly pulling stuff from the API and showing it. So there isn't enough actual 'logic' to warrant MVC, only simpler "layout logic" (like re-order, truncate, etc). This is why I'm mourning the loss of the (to me) perfect solution of <?foreach():?>

One confusing thing is that quite a lot of hosts still allow shorttags with php 7+, just not all..... I'm sure there is a discussion somewhere about shorttags, but it seems it's not 100% consensus that they need to go.

But I should probably just get used to some MVC templating 🙂

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.