3fingers Posted December 8, 2016 Posted December 8, 2016 Hello guys, here is my messy code, I'm here to ask for a help in refactoring a foreach loop: $grandchildred = $page->children(); foreach ($grandchildred as $grandchild) { $children = $grandchild->children(); $outGrandchild = ''; /* MARKUP FOR GRANDCHILD */ $outGrandchild.= "<div class='uk-grid uk-grid-large'>"; $outGrandchild.= "<div class='uk-width-medium-1-3'>"; $outGrandchild.= "<div class='uk-panel uk-panel-box prodotto__panel-mod'>"; $outGrandchild.= "<div class='uk-panel-teaser'>"; $outGrandchild.= "<div class='uk-cover-background' style='background-image: url({$grandchild->product_image->url});'>"; $outGrandchild.= "<img class='uk-invisible' src='{$grandchild->product_image->url}' width='600' height='400' alt='Placeholder'>"; $outGrandchild.= "</div></div></div>"; $outGrandchild.= "<a class='prodotto__panel-links prodotto__panel-links-blue' href='{$grandchild->url}'><span>Discover more</span></a>"; $outGrandchild.= "</div>"; $outGrandchild.= "<div class='uk-width-medium-2-3'>"; $outGrandchild.= "<div class='prodotto__descr'><span>{$grandchild->product_options->title}</span>"; $outGrandchild.= "<h3 class='shadow-blue'>{$grandchild->title}</h3>"; $summary = truncateText($grandchild->product_description); $outGrandchild.= "<p>{$summary}</p><p><a href='{$grandchild->url}'><i class='uk-icon-chevron-circle-right uk-margin-small-right'></i>Link</a></p>"; $outGrandchild.= "</div></div></div>"; $outChild = ''; foreach ($children as $child) { /* MARKUP FOR CHILDREN - IT'S THE SAME AS ABOVE */ // HOW CAN I AVOID TO REWRITE IT? $outChild.= "<div class='uk-grid uk-grid-large'>"; $outChild.= "<div class='uk-width-medium-1-3'>"; $outChild.= "<div class='uk-panel uk-panel-box prodotto__panel-mod'>"; $outChild.= "<div class='uk-panel-teaser'>"; $outChild.= "<div class='uk-cover-background' style='background-image: url({$child->product_image->first()->url});'>"; $outChild.= "<img class='uk-invisible' src='{$child->product_image->first()->url}' width='600' height='400' alt='Placeholder'>"; $outChild.= "</div></div></div>"; $outChild.= "<a class='prodotto__panel-links prodotto__panel-links-blue' href='{$child->url}'><span>Discover more</span></a>"; $outChild.= "</div>"; $outChild.= "<div class='uk-width-medium-2-3'>"; $outChild.= "<div class='prodotto__descr'><span>{$child->product_options->title}</span>"; $outChild.= "<h3 class='shadow-blue'>{$child->title}</h3>"; $summary = truncateText($child->product_description); $outChild.= "<p>{$summary}</p><p><a href='{$child->url}'><i class='uk-icon-chevron-circle-right uk-margin-small-right'></i>Link</a></p>"; $outChild.= "</div></div></div>"; } /* OUTPUT CONDITION */ if(!count($grandchild->children())){ echo $outGrandchild; } else { echo $outChild; } } $grandchild and $children shares the same markup, but sometimes I just want to echo out $grindchild when they haven't $children. How can I code this in a more elegant way?
Macrura Posted December 8, 2016 Posted December 8, 2016 <?php function renderUkGrid($page) { $summary = truncateText($page->product_description); $out = "<div class='uk-grid uk-grid-large'>"; $out .= "<div class='uk-width-medium-1-3'>"; $out .= "<div class='uk-panel uk-panel-box prodotto__panel-mod'>"; $out .= "<div class='uk-panel-teaser'>"; $out .= "<div class='uk-cover-background' style='background-image: url({$page->product_image->url});'>"; $out .= "<img class='uk-invisible' src='{$page->product_image->url}' width='600' height='400' alt='Placeholder'>"; $out .= "</div></div></div>"; $out .= "<a class='prodotto__panel-links prodotto__panel-links-blue' href='{$page->url}'><span>Discover more</span></a>"; $out .= "</div>"; $out .= "<div class='uk-width-medium-2-3'>"; $out .= "<div class='prodotto__descr'><span>{$page>product_options->title}</span>"; $out .= "<h3 class='shadow-blue'>{$page->title}</h3>"; $out .= "<p>{$summary}</p><p><a href='{$page->url}'><i class='uk-icon-chevron-circle-right uk-margin-small-right'></i>Link</a></p>"; $out .= "</div></div></div>"; return $out; } foreach($page->children() as $grandchild) { if($grandchild->children()) { foreach($grandchild->children() as $child) { echo renderUkGrid($child); } } else { echo renderUkGrid($grandchild); } } i think this is how i would do it, or i wouldn't use a function, and have a partial for the markup and then do a wireRenderFile(); in either case i would keep the markup out of the loop.. 1
blynx Posted December 8, 2016 Posted December 8, 2016 This is very exemplary and you have to apply it to your loop, still: But you can put the small piece into a seperate .php file - for example /templates/partials/piece.php Have a look at http://processwire.com/api/ref/files/render/ Then, you could: <?php // template file $output = $files->render('partials/piece.php', ['value' => $data]) // or with the loop $output = '' foreach($items as $item) { $output .= $files->render('partials/piece.php', ['value' => $item]) } The partial piece.php could be this, I really like the php style to have plain HTML and only insert small php tags where necessary: (It looks nice in my editor, too) <div class="some-grid"> <div> <?= $value->object_prop ?> </div> <div> <?= $value['array_elem'] ?> </div> <ul> <?php foreach($value->data as $item): ?> <li><?= $item->property ?></li> <?php endforeach ?> </ul> </div> PS: You might also want to have a look at https://processwire.com/blog/posts/processwire-3.0.7-expands-field-rendering-page-path-history-and-more/ "field rendering with template files" - again, I am recommending the same stuff all over - but it really helps structuring the files. 2
3fingers Posted December 8, 2016 Author Posted December 8, 2016 You are both providing good adivices and code. I did dozen times what @Macrura wrote...but that's what happens when you got a 5 months baby crying all night long: your mind blows :). Thanks @blynx too, I'm going to investigate more on It. 1
adrian Posted December 8, 2016 Posted December 8, 2016 Based on @Macrura's example - maybe just a personal preference more than anything, but I prefer the look of this. I do think it really helps to indent the code though function renderUkGrid($page) { return " <div class='uk-grid uk-grid-large'> <div class='uk-width-medium-1-3'> <div class='uk-panel uk-panel-box prodotto__panel-mod'> <div class='uk-panel-teaser'> <div class='uk-cover-background' style='background-image: url({$page->product_image->url});'> <img class='uk-invisible' src='{$page->product_image->url}' width='600' height='400' alt='Placeholder'> </div> </div> </div> <a class='prodotto__panel-links prodotto__panel-links-blue' href='{$page->url}'><span>Discover more</span></a> </div> <div class='uk-width-medium-2-3'> <div class='prodotto__descr'><span>{$page>product_options->title}</span> <h3 class='shadow-blue'>{$page->title}</h3> <p>".truncateText($page->product_description)."</p> <p><a href='{$page->url}'><i class='uk-icon-chevron-circle-right uk-margin-small-right'></i>Link</a></p> </div> </div> </div> "; } 2
tpr Posted December 8, 2016 Posted December 8, 2016 Definitely better - I would also recommend looking into the heredoc syntax. 2
BitPoet Posted December 8, 2016 Posted December 8, 2016 2 hours ago, blynx said: $output = $files->render('partials/piece.php', ['child', $data]) Shouldn't that read 'piece' instead of 'child', since you're using $piece in piece.php? 1
blynx Posted December 8, 2016 Posted December 8, 2016 @BitPoet Yep! Thanks! I corrected it and took a more generic name - also I had commas instead of '=>' !! The point is, the keys of the array passed in $files->render() become exposed as variables in the fetched .php partial.
Martijn Geerts Posted December 8, 2016 Posted December 8, 2016 I have a slightly different pattern as @adrian & @Macrura, this way there are no un necessary whitespace characters in HTML $out = "<div class='uk-grid uk-grid-large'>" . "<div class='uk-width-medium-1-3'>" . "<div class='uk-panel uk-panel-box prodotto__panel-mod'>" . "<div class='uk-panel-teaser'>" . "<div class='uk-cover-background' style='background-image: url(" . $page->product_image->url . ");'>" . "<img class='uk-invisible' src='" . $page->product_image->url . "' width='600' height='400' alt='Placeholder'>" . "</div>" . "</div>" . "</div>" . "<a class='prodotto__panel-links prodotto__panel-links-blue' href='" . $page->url . "'>" . "<span>Discover more</span>" . "</a>" . "</div>" . "<div class='uk-width-medium-2-3'>" . "<div class='prodotto__descr'>" . "<span>" . $page->product_options->title . "</span>" . "<h3 class='shadow-blue'>" . $page->title . "</h3>" . "<p>" . (truncateText($child->product_description)) . "</p>" . "<p>" . "<a href='" . $page->url . "'>" . "<i class='uk-icon-chevron-circle-right uk-margin-small-right'></i>Link". "</a>" . "</p>" . "</div>" . "</div>" . "</div>"; 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now