I am trying to rewrite the RSS Feed Parser PHP Code to Smarty. The Smarty will not work for me somehow. Can somebody help me out please?
<ul>
<?php foreach ($feed['items'] as $item): ?>
<li>
<?= $item['title']; ?>
</li>
<?php endforeach; ?>
</ul>
My Smarty Code Updated: 12/07/13
{foreach name=aussen item=$feed.items from=$item}
<li>
{$item.title}
</li>
{/foreach}
There are a lot of issues with your smarty code. First, and foremost, you should NOT have php logic and smarty formatting in the same file. You should assign smarty variables separately and then call smarty for formatting. However if you stick with your existing stuff, you'll need to take into account the following:
syntax of your foreach is wrong - the correct syntax is {foreach from=$variable item=$loop_var}
php variables are not automatically available in smarty - you'll need to add smarty {assign} directive with a combination of{php}echo $php_var{/php}` to get php variable to smarty.
syntax {php}$item['title']{/php} is invalid syntax for php and will result in syntax error.
On the whole, your approach is flawed. Smarty is good for a presentation (view) layer in an MVC app - and you're trying to combine everything into one file. Don't. If you are not sure how to set your application properly as MVC, then smarty is not for you.
Related
I'm trying to use php-cs-fixer with a WordPress project, which means I (unfortunately) have files with a mix of PHP and HTML. I'm using the #PSR12 ruleset.
I'm having trouble with getting HTML within PHP control structures to indent correctly. Take this example snippet:
<?php if (!empty($related_posts)) : ?>
<div class="module--related_posts alignfull has-2-columns has-hover-state slider-on-mobile">
<h3 class="has-text-align-center">Related <?= esc_html($title) ?></h3>
</div>
<?php endif ?>
php-cs-fixer reformats it to:
<?php if (!empty($related_posts)) : ?>
<div class="module--related_posts alignfull has-2-columns has-hover-state slider-on-mobile">
<h3 class="has-text-align-center">Related <?= esc_html($title) ?>
</h3>
</div>
<?php endif ?>
Note the closing h3 tag has been moved to a new line, and the first-level indent within the if statement body has been removed.
The h3 issue I can live with, as this is resolved if I put the opening tag on its own line:
<h3 class="has-text-align-center">
Related <?= esc_html($title) ?>
</h3>
...but the lack of indent within the if statement is going to do my head in. The same thing happens with for and while statements.
Is there a rule in php-cs-fixer that I've overlooked that will resolve this?
The Answer of keradus on the "PHP code does not align with html code" issue:
PHP CS Fixer was never written with supporting mixed html/php file.
Some fixers are supporting one php part and one html part inside single file, but not big mix of them, like in template files.
If we would like to support template files, we would need to not only detect and track concrete fixers, but also provide some big integration test (like we do for Sf ruleset) that it remains to work for most important rules.
Before that happen, I would not claim that we officially support html/php mixed-files.
And in another answer:
we do not aim to fix mixed file (PHP and HTML in single file)
Not really an answer but I ended up just switching to PHP_CodeSniffer to get around this.
I'm working on a legacy application that is written in PHPfox.
There is this foreach loop in one of my view.html.php files:
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
<td>{$aReportSubmission.event_name}</td>
{/foreach}
The problem is that $aReportSubmission.event_name is an array and it gets outputted as Array. How can I loop through this variable and show the individual events?
PHPfox uses template tags that resemble Smarty template engine.
The following did NOT work for me:
{foreach from=$aReportSubmission.event_name item=iEvent} {iEvent},{/foreach}
I can see $ is missing before iEvent inside the inner loop
Check if this is works
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
<td>{foreach from=$aReportSubmission.event_name item=iEvent} {$iEvent},{/foreach}</td>
{/foreach}
Try with this
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
{$aReportSubmission.event_name|print_r}
{/foreach}
How to structure view hierarchy without using blade? What are the pure php counterparts of blade directives (i,e #section, #extend , etc)?
Perhaps, something similar to <?php extend('foo') ?>
In Phalcon framework, while it has its own template engine (Volt) all of its template engine is also available in pure PHP syntax.
Since Blade directives just compile to normal PHP, it is technically possible to use the view structuring features without actually using Blade. I don't think it's very pretty though, and I personally would think twice about this decision.
You can find all the PHP code, Blade is compiled to, in this class:
Illuminate\View\Compilers\BladeCompiler
Here are some of them:
#section('content')
<?php $__env->startSection('content'); ?>
#endsection
<?php $__env->stopSection(); ?>
#extends('layout')
This is a bit a tricky one. Usually Blade compiles it and then adds it to a footer variable which is printed at the bottom. So instead of putting it at the top (like you would with #extends) you have to place this at the end of your view:
<?php echo $__env->make('layout', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>
#yield('content')
<?php echo $__env->yieldContent('content'); ?>
To put this in a pure PHP way you'll have to check out the storage/framework/cache/views and see what's happening there. Basically, is what Blade compiles to PHP code (instead of using # and with proper function calls).
One way I can think is:
In your template where you use yield:
<!-- template.php -->
<div class="container">
<!-- instead of using yield('container') -->
<?php echo "_yield:container"; ?>
</div>
In your file, instead of using section and stop
<!-- view.php -->
<!-- instead of using extend('template') -->
<?php $templatePath = 'template.php'; ?>
<?php $sections = []; ?>
<!-- instead of using section('container') -->
<?php $currentSectionName = 'container'; ob_start(); ?>
<p>This will be in my container div</p>
<!-- instead of using stop -->
<?php
// get the current html
$sections["_yield:".$currentSectionName] = ob_get_contents();
ob_end_clean();
ob_start();
require($templateName);
$template = ob_get_contents();
ob_end_clean();
echo str_replace($template,array_keys($sections),array_values($sections));
?>
Of course, this approach is simplistic at best. The code provided is not intended as a copy & paste solution, more like the concept.
Everything else is simple:
#foreach($arr as $k=>$v)
...
#endforeach
translates to
<?php foreach($arr as $k=>$v) : ?>
...
<?php endforeach; ?>
That's how it's exactly done by the BladeCompiler. The same is with if and while.
The pure PHP equivalent to Blade is to split your code in sections like header and footer (for example) and then use require in your page to blend those sections in the corresponding place.
<?php
require("template/header.php");
// Here goes the body code
require("template/footer.php");
?>
There is no pure PHP functions that i can think of, to extend a page from a main template, a you do using the yield directive.
Blade compiles into PHP every time and what it compiles is stored in to storage/framework/views/*
The following link is a list of all things blade can compile to, you should be able to extract some knowledge out of this:
https://github.com/illuminate/view/blob/master/Compilers/BladeCompiler.php
The general idea for most templating engine is that they structure your code like so:
if ($condition):
// do stuff
endif;
while ($condition):
// do stuff
endwhile;
foreach ($array as $key => $value):
// do stuff
endforeach;
For further reference, see https://secure.php.net/manual/en/control-structures.alternative-syntax.php
Neither of blade directives is a 'pure' PHP function. PHP functions cannot start with # and all blade directives do. In short, blade directives are shortcuts or synonyms to PHP built-in functions or control structures.
You are free to use any other template engine – it doesn't have to be Blade. Blade is built-in, but you are not locked to it. Just install a vendor package or make your own one, and return your HTML output with response, instead of using View facade.
I am currently working on moving an expression engine site from one server to another and i noticed one issue i am having a hardtime debugging. When i upload an logo image all seems fine but the index.php page that the logo is displayed on it has this code
{embed="shared/head"}
<body class="{if segment_1 == ''}home{if:else}{segment_1}{/if}">
<div id="page" class="container">
<div class="span-22 prepend-1 append-1 last">
{embed="shared/masthead"}
{if logo !=''}
<div class="news_item_logo">
{organization}
{if link}<img src="{logo}" width="130" alt="{title}" />{if:else}
<img src="{logo}" width="130" alt="{title}" />{/if}
{/organization}
</div><!-- /.news_item_logo -->
<ul>
<li><h3>{title}</h3></li>
<li>{pub_date}</li>
{organization}
<li>{if link}{/if}{exp:php_text_format type="lowercase"}{if url_text != ''}{url_text}{if:else}{name}{/if}{if link}{/exp:php_text_format}{/if}</li>
{/organization}
<li>{if file}PDF{/if}{if web_link !='' AND file !=''} | {/if}{if web_link}HTML{/if}</li>
</ul>
{if:else}
<ul class="no_logo">
<li><h3>{title}</h3></li>
My question is this, I see curly brackets {} around if statements and i want to know first what language it is and second is there a way to debug like php print_r() because the code always goes to the else with the no_logo class and i want to know what and how i can test these variables "segment1" and "logo" and "organization" and "url" How do and where do i inspect these variables
You can gain some info about the given variables and values in the template using the following within your index.php:
<?php
$EE = get_instance();
var_dump($this->EE->TMPL);
?>
Note that PHP must be enabled in templates for that to work (see PHP in Templates).
{embed="shared/head"} - include the template head from the template group shared
<body class="{if segment_1 == ''}home{if:else}{segment_1}{/if}">
if the URI segment (EE/CI works with segments eg site.com/segment1/segment2/xxx) is empty (you are on the home page (www.site.com), then add no body class.
else, the user is on a page (in EE this is a template group), so set the class to be the name of the template group.
site.com/about-us produces class="about-us" - handy for page specific styling.
{embed="shared/masthead"} - include masthead
and so on.
The rest are conditionals to check if the variables have values, and outputs them
I presume you're using EE2.0, I'm not sure what {organizaton} is specifically, but that style:
{organization} {foo} {/organization}
in code igniter at least, is generally the equivalent of a foreach or looping through a recordset:
foreach($organizations as $organization) { // do something }
This is written in Expression Engine's own templating language.
You would have to check the documentation to see whether there is any way to debug variables.
Possibly helpful links:
Quick Reference Chart
PHP in Templates
I want to keep my templates tidy and nicely intented but would like to deliver only very compact HTML to the browser.
Missing a better idea, I was wondering if there is something wrong with wrapping whole Smarty templates in {strip} tags like so?
{strip}
<div class="albums">
<h2>Alle Foto-Alben</h2>
<ul class="photos clearfix">
{foreach $albums as $album}
{if $album->publishedPhotos|count > 0}
<li>
<div>
<a href="album.php?id={$album->id}">
<img src="{$album->titlepic->thumb}" alt="{$album->titlepic->title}" />
<span class="title">{$album->title}</span>
<span class="counter">{$album->publishedPhotos|count} Foto{if $album->publishedPhotos|count != 1}s{/if}</span>
</a>
</div>
</li>
{/if}
{/foreach}
</ul>
</div>
{/strip}
It smells a bit unprofessional to me but I could not come up with something better.
One downside definitely is that you have to wrap every single one of your templates in those tags.
I'm happy to be corrected and would love to hear different approaches to keeping delivered code compact.
While it's not wrong i would suggest using a pre-filter instead. A pre-filter only runs when the template is compiling (so it doesn't slow down the server) and you don't need to wrap every template in {strip}. The following rows of code is taken from a project I am working on. It effectively strips most whitespace.
/* Minify the html */
function smarty_pre_minify($tpl_source, $smarty) { return preg_replace('/[ \t\n\r]+/s', ' ', $tpl_source); }
$smarty->registerFilter('pre', 'smarty_pre_minify');
Nope, there's nothing wrong with this.
Do it in a header/footer pair of templates, rather than wrapping each page individually.
Alternately, you could trigger the stripping on the PHP side of things.
Notice: Striptags will ignore includes. Free tip of the day. :-)