CakePHP Recommended syntax for templates (views) - php

Ever since i've used CakePHP, I asked myself about the deeper sense of the recommended syntax of CTP-files, which is basically a HTML-file with all PHP code bracketed with tags. I find this very hard to read and I should think that the context switches between HTML and PHP would add some performance penalty.
Wouldn't it be faster and clearer to collect all output in a string and echo it at the end?
But there is some deeper sense for sure, just that i don't see it..
To make myself clearer, here's an example:
CakePHP:
<?php if (!empty($file['User']['email'])): ?>
<div class="mailto"><?php echo $this->Html->link($file['User']); ?></div>
<?php endif; ?>
<?php if (!empty($file['Document']['comments'])): ?>
<div class="file-comment file-extra column grid_6">
<div class="content"><?php echo $file['Document']['comments']?></div>
</div>
<?php endif; ?>
My approach:
<?php
$out = '';
if (!empty($file['User']['email'])) {
$out .= '<div class="mailto">'.$this->Html->link($file['User']).'</div>';
}
if (!empty($file['Document']['comments'])) {
$out .= '<div class="file-comment file-extra column grid_6">'
.'<div class="content">'.$file['Document']['comments'].'</div>'
.'</div>';
}
echo $out;
?>
So my question is: What are the drawbacks to my approach compared to CakePHP's ?

First things first: writing your entire template as PHP, then echoing it is not a great idea. As a general rule of thumb, I avoid echoing HTML from PHP ever, if I can. there are many reasons, but the main one will be the lack of syntax highlighting in your IDE.
Anyway, code formatting is entirely down to personal preference, but if you're writing your templates like this:
<?php if (!empty($file['User']['email'])): ?>
<div class="mailto"><?php echo $this->Html->link($file['User']); ?></div>
<?php endif; ?>
<?php if (!empty($file['Document']['comments'])): ?>
<div class="file-comment file-extra column grid_6">
<div class="content"><?php echo $file['Document']['comments']?></div>
</div>
<?php endif; ?>
...it's no wonder you can't read them.
There are a few things you could try, to make your code clearer and easier to read. Again, these are down to your own personal preferences, and you could get into the habit of using some or all of them.
Format your HTML properly, with indentations for child elements.
Add white space between lines of code that are too busy, particularly between lines of PHP and lines of HTML.
Use short echo tags syntax (<?= instead of <?php echo).
Assign the more complex PHP values to variables so that your HTML is easier to read.
Remember to comment your code (HTML or PHP), particularly adding HTML comments so that you can easily see separate components of your template at a glance.
Example
<?php
$user = $file['User'];
$comments = $file['Document']['comments'];
?>
<!-- User -->
<?php if (!empty($user['email'])) : ?>
<div class="mailto"><?= $this->Html->link($user); ?></div>
<?php endif; ?>
<!-- File Comments -->
<?php if (!empty($comments)) : ?>
<div class="file-comment file-extra column grid_6">
<div class="content"><?= $comments; ?></div>
</div>
<?php endif; ?>

Related

Echo an image tag with site_url() inside PHP tags

I have a loop in my view that outputs all the content gathered from the database:
<?php foreach($content as $contentRow): ?>
<?php
echo $contentRow->value;
?>
<?php endforeach; ?>
This works fine for HTML strings like:
<h2><strong>Example Text</strong></h2>
however I have some image content that I would like to display and I have tried the following database entries to no avail:
<img src="<?php echo site_url('pathToImage/Image.png'); ?>" alt="Cover">"
<img src="site_url('pathToImage/Image.png')" alt="Cover\">"
I feel like I am missing a step on how to use PHP values in this way.
How do I access the URL of the image and use that to show the image?
Full Code Edit
<?php
$CI =& get_instance();
?>
<div class="container">
<div class="row">
<div class="col-md-9">
<div class="col-md-2"></div>
<div class="col-md-20">
<!--<form class="form-center" method="post" action="<?php echo site_url(''); ?>" role="form">-->
<!-- <h2 class="">Title</h2>
<h2 class=""SubTitle/h2>-->
<?php echo $this->session->userdata('someValue'); ?>
<!--//<table class="" id="">-->
<?php foreach($content as $contentRow): ?>
<tr>
<td><?php
echo $contentRow->value;
?></td>
</tr>
<?php endforeach; ?>
<!--</table>-->
<!--</form>-->
</div>
<div class="col-md-2"></div>
</div>
</div>
</div><!-- /.container -->
and the values are being read out in $contentRow->value;
I have to verify this, but to me it looks like you are echo'ing a string with a PHP function. The function site_url() is not executed, but simply displayed. You can execute it by running the eval() function. But I have to add this function can be very dangerous and its use is not recommended.
Update:
To sum up some comments: The use of eval() is discouraged! You should reconsider / rethink your design. Maybe the use of tags which are replaced by HTML are a solution (Thanks to Manfred Radlwimmer). Always keep in mind to never trust the data you display, always filter and check!
I'm not going to accept this answer as #Philipp Palmtag's answer helped me out alot more and this is more supplementary information.
Because I'm reading data from the database it seems a sensible place to leave some information about what content is stored. In the same table that the content is stored I have added a "content type" field.
In my view I can then read this content type and render appropriately for the content that is stored. If it is just text I can leave it as HTML markup, images all I need to do is specify the file path and then I can scale this as I see fit.
I have updated my view to something akin to this and the if/else statement can be added to in the future if required:
<?php foreach($content as $contentRow): ?>
<?php if ($contentRow->type != "image"): ?>
<?php echo $contentRow->value; ?>
<?php else: ?>
<?php echo "<img src=\"".site_url($contentRow->value)."\">"; ?>
<?php endif; ?>
<?php endforeach; ?>

What is this convention of using php code inside the first html tags?

I was referring the page.tpl.php(Drupal 7 theme) for understanding the code. I found the following code,
<?php if ($site_name || $site_slogan): ?>
<!-- !Site name and Slogan -->
<div<?php print $hgroup_attributes; ?>>
<?php if ($site_name): ?>
<h1<?php print $site_name_attributes; ?>><?php print $site_name; ?></h1>
<?php endif; ?>
<?php if ($site_slogan): ?>
<h2<?php print $site_slogan_attributes; ?>><?php print $site_slogan; ?></h2>
<?php endif; ?>
</div>
<?php endif; ?>
Can you see the code in third line, <div<?php print $hgroup_attributes; ?>> WHY the php code is inside the first div tag of html? Same thing in later part of code also, as you can see h1 and h2 code. So, what is this convention of combining the html and php in so complicated way? and how should I read that?
Combining HTML and PHP code in Drupal templates is actually a very strong feature. In this case, $hgroup_attributes will probably contain some classes that style the div. Printing it in the template results in something like
<div class="SOME_CLASSES"> ... </div>
If you're further interested in the variable $hgroup_attributes, you can inspect by pasting <?php dpm($hgroup_attributes); ?> in your template file after you've installed the Devel module.

How can I use an associative array inside an <<<_END html tag?

I'm building my own little blogging platform as a practice/fun/exercise in PHP and MySQL. I'm currently using the following code to output the proper formatting (which works perfectly):
$rows=mysql_num_rows($postsresult);
for ($j=0 ; $j < $rows ; ++$j){
$row=mysql_fetch_row($postsresult);
echo <<<_END
<div class="titlebox"> $row[3] </div>
<div class="maincontent"> $row[2]
<div class="postclosercontainer">
<div class="postcloser">Sincerely, <br />
Samuel'<span>Explosion Festival</span>' Shenaniganfest </div>
</div></div>
_END;
}
However, I found that the while($info=mysql_fetch_array($postsresult){ would be easier to code for, as the data is stored by name instead of by array number (which, with any more than a few fields, becomes aggravating to remember).
I tried to update the code with the prior while loop, but found that when I went to pull the data from the array by name, it no longer functioned properly within the <<<_END tags.
For example: <div class="titlebox"> $data['title'] generates an error.
Is there any way to accomplish this within the <<<_END tags, or should I just use the print function for each line? On a another note, is this even proper coding technique? (I'm only an amateur.)
Better is to directly write HTML. This makes it easier to maintain your HTML and you might be able to use features from your IDE such as syntax highlighting or code completion.
Example:
<?php
// your other code
?>
<?php while(($info=mysql_fetch_array($postsresult))): ?>
<div class="titlebox"><?php echo $info['title']; ?> </div>
<div class="maincontent">
<?php echo $info['content']; ?>
<div class="postclosercontainer">
<div class="postcloser">Sincerely, <br />
Samuel'<span>Explosion Festival</span>' Shenaniganfest
</div>
</div>
</div>
<?php endwhile; ?>
I'm using the alternative syntax for control structures. It increases readability when dealing with HTML, especially if you have nested control structures (brackets are much more difficult to spot when embedded in HTML).

Help with a php if statement

can somebody help me with this if statement?
My form appears every-time I load the page but it disappears after I submit the form!
Maybe it's the "endif" syntax that confuses me but I can't get this done properly...
here is the code:
<?php
if ($this->input->post('submit') && $this->input->post('categories')):
foreach($tagedImages as $image):
?>
<div class="thumb">
<?php echo'<a href="/toKoritsi/uploads/'.$image.'"/> <img src="/toKoritsi/uploads/thumbs/'.$image.'"/></a>' ?>
</div>
<?php
endforeach;
elseif(isset($photosQuery) && count($photosQuery)):
foreach($photosQuery->result_array() as $photo):
?>
<div class="thumb">
<?php echo'<a href="/toKoritsi/uploads/'.$photo['name'].'"/> <img src="/toKoritsi/uploads/thumbs/'.$photo['name'].'"/></a>' ?>
</div>
<?php
endforeach;
endif;
$options = array(
'bracelet' => 'Bracelets',
'ring' => 'Rings',
'bag' => 'Bags',
'earing' => 'Earings'
);
echo form_open("toKoritsi/gallery");
echo form_dropdown('categories', $options, 'bracelet');
echo form_submit('submit', 'Choose');
echo form_close();
?>
thanks in advance!
Should foreach($tagedImages as $image) be foreach($taggedImages as $image)?
The formatting of your code is very ugly. If you are intent on getting nicely-formatted HTML output, perhaps you should consider using Tidy, or a template engine that offers that functionality.
I donĀ“t know what the url structure of your site looks like, but are you sure you are submitting the form to the right place?
According to the CI user guide, it gets submitted to something like /index.php/toKoritsi/gallery but that depends on your config preferences.
You definitely need to format your code properly.
I'd also recommend trying to consolidate your PHP into blocks, and keep it separate from your HTML.
You can do all the conditionals and echos WITHIN some of those HTML elements:
<div>
<?php /*...*/ ?>
</div>
as opposed to what you're doing now:
<?php /*...*/ ?>
<div>
<?php /*...*/ ?>
</div>
<?php /*...*/ ?>
In addition, things like these blocks make no sense:
<?php endforeach;?>
<?php endif;?>
Even if you had to break your code into small chunks, wouldn't it be easier to say:
<?php
endforeach;
endif;
?>
EDIT: This answer was provided before the question source was reformatted and cleaned up. I was unable to even address the original issue until I could better see what was going on.
This might sound kind of dumb, but are you sure that your gallery controller is behaving correctly? If you're submitting and there's an error in one of your CodeIgniter functions, it could be messing up the rendering after the submit.

How do I insert an HTML page using PHP?

I wanted to know, is there any way to insert an HTML page into PHP without using the include function? I do not want to use an external html file, I want to write the html coding directly into the php coding.
Thanks for your help!
Interleave it:
<?php
// Some php code.
?>
<html>
<head>
<title>Hello!</title>
</head>
<body>
<h1>Header</h1>
<?php /* More php code. */ ?>
<p>Blah!</a>
</body>
</html>
<?php /* Even more php. */ ?>
From a best practices point of view, though, avoid doing this - having business logic (PHP) and presentation (HTML) in the same place makes maintaining harder.
EDIT: To address your comment. You can either do it the same way, or use echo:
<?php if (x == 5) { ?>
<p>Blah!</a>
<?php } else {
echo '<p>Bleh</p>';
} ?>
If you need to include snippets of HTML based on conditions, you can interleave code like this. In this case it's convenient to use the alternative syntax for loop controls
<?php if ( $var ): ?>
<html>
<title>YAY</title>
</html>
<?php endif; ?>
so the code is clearer to read and you retain HTML syntax coloring (if your editor supports it).
It is very bad habit to mix HTML and PHP (for more than just output control), but here you go:
$html = "<div>This is HTML</div>"
echo $html;
or Heredoc syntax:
$html = <<<EOF
<div>
<p>
Some longer HTML
</p>
</div>
EOF;
echo $html;
or using alternative syntax for control statements if the output depends on some condition (or if you loop through an array etc.)(which is far better than building HTML with strings):
<?php if($foo): ?>
<div> Some HTML output </div>
<?php else: ?>
<div> Some other HTML </div>
<?php endif; ?>
or just
<?php //PHP here ?>
<div>HTML</div>
<?php //more PHP ?>
<div>more HTML</div>
<?php //even more PHP ?>

Categories