Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve Data Inside Templates: loops #38

Open
plweil opened this issue Aug 27, 2016 · 14 comments
Open

Retrieve Data Inside Templates: loops #38

plweil opened this issue Aug 27, 2016 · 14 comments

Comments

@plweil
Copy link

plweil commented Aug 27, 2016

Can you use helpers for echoing variables while iterating through an array? All I have been able to do is something like this:

<?php foreach ($this->news_stories as $story): ?>
  <li><?= $story['title'] ?></li>
<?php endforeach ?>

Are there any other options for doing this?I'm not sure whether this is providing an escaping or other benefits of helpers.

@plweil
Copy link
Author

plweil commented Aug 29, 2016

Just to provide a little more context, I am pulling in data via a remote json file (basically a news feed) and need to echo out the headline and url (and maybe more) for each story item. So I don't have any control over the data; it could contain html, or anything for that matter. I can tell json_decode whether I want an object or an array; it seems that with Foil, an array is preferable. Do you have any recommendations for the safest way to echo each of these in Foil? Thank you.

@thinsoldier
Copy link

thinsoldier commented Aug 31, 2016

Loop over the array and apply Foil's escaping function (if there is one) or your own escaping techniques to every value in the array. Then when you use those values they have already been escaped.

This is just a guess. I've not actually used Foil yet.

From what I read a minute ago Foil supposedly ships with some 3rd party utility that makes applying a function to every value within a deeply nested array of every possible type of value very easy and reliable. This might be it: https://github.com/FoilPHP/Foil/blob/master/src/Kernel/Arraize.php

@plweil
Copy link
Author

plweil commented Aug 31, 2016

Thanks. I did finally find one example in the docs, which uses the a() helper. So what I'm doing is this:

<?php foreach ($this->a('news_stories') as $story): ?>
<li><h3><a href="<?= $story['url'] ?>"><?= $story['headline'] ?></a></h3></li>
<?php endforeach ?>

Personally, I find the $var['array-item'] syntax pretty ugly, and prefer the dot syntax you get with Twig and Blade. I was hoping that I could use that this situation, but it doesn't seem to be possible; i.e.,

"All helpers support dot syntax to access variables in nested arrays."

@thinsoldier
Copy link

thinsoldier commented Aug 31, 2016

<? foreach ($this->a('news_stories') as $story){ 
$story = (object) $story; ?>
<li><h3><a href="<?= $story->url ?>"><?= $story->headline ?></a></h3></li>
<? } ?>
<? foreach ($this->a('news_stories') as $story){ 
extract( $story ); ?>
<li><h3><a href="<?= $url ?>"><?= $headline ?></a></h3></li>
<? } ?>
<? 
$listItemFormat = '<li><h3><a href="%s"> %s </a></h3></li>';
foreach ($this->a('news_stories') as $story)
{ 
  extract( $story );
  printf( $listItemFormat, $url, $headline );
}
?>

(I will never understand people's preference for if/endif and foreach/endforeach syntax when you chose to use Foil BECAUSE it allows full normal php syntax)

@plweil
Copy link
Author

plweil commented Aug 31, 2016

Thanks, I hadn't thought of those. I do like the second one; it looks the cleanest. I was also considering a printf() for this (and may yet decide to do so), especially since some elements may contain several variables strung together. As for the foreach syntax, it's a personal preference. I've never cared for putting the closing bracket within its own php tag. And it's the ugliness of php as a templating language that has driven me towards things like twig (esp. for WordPress). Thanks again for your suggestions.

@thinsoldier
Copy link

I've got a view that produces sightly different thumbnail markup based on
number of photos (0, 1, 2-3, 4-6, > 12), whether or not the first 2 photos
have the same file name but different paths, whether or not a photo is from
within the site folder or third party server, whether or not the article
was imported from a third party or local or exists on both, whether or not
there is 1 or more videos and whether this videos are local or YouTube and
whether or not the author was entered or set to override the real author
with another author or hide the author manually or the author is no longer
with the company but we still want to show her name or is no longer with
the company so show someone else or is no longer alive so make it
completely different.... There's a lot of if/else purely related to
deciding what to show or not show. Without being able to collapse and
expand and auto select text within {...} It would be a pain to work on that
thing.

On Aug 31, 2016 10:30 AM, "plweil" notifications@github.com wrote:

Thanks, I hadn't thought of those. I do like the second one; it looks the
cleanest. I was also considering a printf() for this (and may yet decide to
do so), especially since some elements may contain several variables strung
together. As for the foreach syntax, it's a personal preference. I've never
cared for putting the closing bracket within its own php tag. And it's the
ugliness of php as a templating language that has driven me towards things
like twig (esp. for WordPress). Thanks again for your suggestions.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#38 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAW0StZsz40kmNVpxsA99raR2bcdKkjRks5qlawbgaJpZM4Juymu
.

@plweil
Copy link
Author

plweil commented Aug 31, 2016

Well, putting a lot of logic into the view is something you want to avoid, if possible (of course you knew that already). No templating language is going to make that much logic very pretty.

@gmazzap
Copy link
Contributor

gmazzap commented Sep 4, 2016

Sorry for late answer, just come back from 2 weeks vacation.

@plweil there are the "Loop Helpers" you can maybe find intersting (see documentation).

They did not (yet) work with associative arrays, but only with ordered array.

For example, assuming 'stories' template variable is an array like this:

[
  ['First Title', 'First Headline', 'http://example.com/first'],
  ['Second Title', 'Second Headline', 'http://example.com/second'],
]

You can do:

$this->walk('stories', '<h1><a href="%3$s">%1$s</a></h1><p>%2$s</p>');

And it will output:

<h1><a href="http://example.com/first">First Title</a></h1><p>First Headline</p>
<h1><a href="http://example.com/second">Second Title</a></h1><p>Second Headline</p>

I understand that this does not work well if the order of various "pieces" of information is not predictable, so I guess some way to use that helpers in combination with array keys would be very nice.

I consider this a "nice to have" feature and I'll leave this issue open as a remined to implement it as soon as I have the time.

@thinsoldier
Copy link

$this->walk('stories', '<h1><a href="%3$s">%1$s</a></h1><p>%2$s</p>');

This appears to be 1 based instead of zero based like the actual array. Is that a typo or actually how it is?

@gmazzap
Copy link
Contributor

gmazzap commented Sep 5, 2016

@thinsoldier it is 1-based because it follows the PHP sprintf pattern and syntax. See expecially the "Argument swapping" example on PHP docs.

@plweil
Copy link
Author

plweil commented Sep 6, 2016

@Giuseppe-Mazzapica: Thanks for your reply. Yes, having a helper that works with array keys would be a nice addition. I've seen a few interesting efforts to solve sprintf's lack of support for associative arrays; e.g., StringTemplate. I think for now I may just go with one of the solutions suggested above by @thinsoldier.

@plweil
Copy link
Author

plweil commented Sep 7, 2016

While we're on the topic of sprintf, another helpful addition would be a helper that returns a formatted string along the lines of Twig's format filter. I have some blocks where using Foil's method for inserting several variables in a sentence is much more tedious and less readable than a simple printf. E.g.,

<?php 
printf('<p id="uw-featured-hero-info">“%s”. %s. Photo ©%s by %s </p>', $title, $description,   $year, $photographer);
?>

versus

<p id="uw-featured-hero-info"><?= '“'.$title.'”. '.$description.'. Photo ©'.$year.' by '.$photographer ?></p>

If there is a handy way to do this with Foil that I am missing, please let me know.

@gmazzap
Copy link
Contributor

gmazzap commented Sep 7, 2016

Note that Foil templates are just PHP files, so you are free (and encouraged) to use any PHP function that makes your life easier and your templates better.

<?= sprintf('<p id="uw-featured-hero-info">“%s”. %s. Photo ©%s by %s</p>', $T->title, $T->description,  $T->year, $T->photographer) ?>

is perfectly valid in Foil templates. I did not add special helper methods for something like this because existing PHP function is enough...

@plweil
Copy link
Author

plweil commented Sep 7, 2016

Ok, thanks Giuseppe. That makes sense.

Peter

On Sep 7, 2016, at 12:58 PM, Giuseppe Mazzapica notifications@github.com wrote:

Note that Foil templates are just PHP files, so you are free (and encouraged) to use any PHP function that makes your life easier and your templates better.

“%s”. %s. Photo ©%s by %s

', $T->title, $T->description, $T->year, $T->photographer) ?>

is perfectly valid in Foil templates. I did not add special helper methods for something like this because existing PHP function is enough...


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants