Basic understanding of variables in loops

Hi,

in the docs I read this:

$items = $pages->listed();

In all the Kirby code I looked - in the example files or the code that was given to me here - there has never been such a declaration.

I guess that thing up there declares a variable first before then using it. This looks a little like Javascript to me (which I also don’t know).

Are the real world examples written in a shorthand version because they miss that declaration.

For example in this loop for a blog article there is no such declaration of a variable first, but rather at the end of the line with that “as”:

 <?php foreach($page->children()->listed()->limit(20) as $blogarticle): ?>

Or am I getting this wrong?

in templates and snippets kirby injects the following variables by default.

  • $kirby = kirby\cms\app instance
  • $site = $kirby->site(), kirby\cms\site
  • $pages = $site->pages(), kirby\cms\pages an collection (pimped array wrapper)
  • $page = current page object, kirby\cms\page

read me about that here: https://getkirby.com/docs/guide/templates/basics#basic-usage

Exactly, this code declare the $items variable, it can then be used, e.g. in a loop, or to further modify it:

foreach ($items as $item) {
  echo $item->title();
}

This is them same as directly using

foreach ($pages->listed() as $item) {
  echo $item->title();
}

Assigning a value to a variable first makes sense if you are going to use it in multiple places, so you don’t have to keep repeating yourself. It also keeps your code clean and short if you define your variables in a controller and then use them in templates and snippets.

Also, the longer your definition, it makes sense to use a variable instead of putting this into a foreach loop:

$blogposts = $page->children()->listed()->filterBy('tags', 'sometag', ',')->sortBy('title')->offset(5)->limit(5);

PHP variable basics: https://www.php.net/manual/de/language.variables.basics.php

So, I can declare a varibale in a statement („as“) if I know it is only used in that one statement.

But if I know I am going to use it pagewide in several statements I need to declare it at the top.

And putting it in a controller is for using it site wide.

Right?

No, a variable you declare in a controller is only valid for templates that use this controller (projects.php controller is use for projects.php template, remember, Kirby works with matching filenames).

Either at the top or in a controller, yes.

I don’t understand what you mean?

Ah, yes of course.

I used the wrong example… This declares a variable right in the statement of a loop in this case, right?

foreach ($pages->listed() as $item) {
  echo $item->title();
}

And this changes a variable, right?


foreach ($blogarticles as $blogarticle): ?>
          /// lalala
<?php endforeach ?>

From plural to singular, no?

Does Kirby or PHP somehow understand that if there is an “s” at the end it is plural and if the “s” is taken away it is meant as singular?

No, these are both foreach loops that loop through something “iterable” (an array, a collection in this case), where the first part is the iterable (no matter if in form of a variable or not) and the thing after the as is the (sort of placeholder) variable each element in that array/collection is assigned to.

See the PHP manual: https://www.php.net/manual/de/control-structures.foreach.php

some variable names are already set by kirby, so you most likely can figure out by name, or by taking a look in the reference, about the content of the variable, other than that, it always depends on you and your data…

<?php
// $pages usually multiple
// $page->children()  -- as children suggests it's a collection
// $file -- usually one result (so no foreach)
// $files -- usually a collection of files..
/* the amount of results in a foreach doesn't really matter as much... 
since it'll work with 1 or 100 results...

*/ 

With your blog example you most likely need to add pagination as well, so as you posted it might still need adjustments. There’s a tutorial for that here too:

For beginners it’s a foreach is easy to understand, i guess it’s much more difficult to get the idea of array, objects, yaml and whatsoever. Like when your content is not in a format you wish to use…

Yeah, thats kind of what I meant.

I could write:

foreach ($blogarticles as $rosenstrauss): ?>
          /// lalala
<?php endforeach ?>

as long as I refer to rosenstrauss from that on?

Yes, you could, but of course you shouldn’t because it is best practice to choose variable names that say something about what’s in that variable.

Obviously, something like

foreach ($c as $a) {
  // do stuff
}

doesn’t give you any idea what is happening here.

That is exactly my problem! Same with Javascript and in a way with other naming conventions. Something like “items as item” is just too universal, too neutral for me. I immediately ask myself " which items?" Same with “name” or “text”. Whose name? And a text field in a blueprint that is like

type: text
label: Text
text: text

makes my brain crash.

To me those namings sounds like a system did that, not a human, not me. I know it is… childish and I try to overcome that, but it is hard :wink:

So for now I try to help myself with a little bit of specificity in that names. “Blogarticle”, not just “article”. “Gotcha-items” not jut plain “items” and so on. And I know, that I could re-use “article” if it is not so specific, but for now, I don’t care so much about “dry”. I probably have a template to many in my folder, but that way I can quickly know what is for what. Also I very often want to make pages or any other kind of element a little different from each other, mostly because of content reasons. So a blog-listing page will probably be a little different from a listing-page of some other kind.

Strangely I love the idea of snippets and use that as “partials” in the way I build my html, using the “kits” thing in CodeKit.