Jump to content

Separate logic from view


Zeka
 Share

Recommended Posts

Hi, all!

Currently, I use wireRender approach, so in template files, I define all logic and in $viewData array I pass all needed data to my view file through wireRedner method.

My question, actually not directly relative to PW, but to data structuring.

Let imagine that we have some page with some repeater field and images field.

In template file, I iterate through $page->images and create new flat array 

$images = [];
foreach ($page->project_images as $image) {
  $images[] = array(
    "desc" => ($image->description) ? $image->description : $page->title,
    "thumb" => $image->size(300, 300)->url,
    "large" => $image->width(800, ['upscaling' => false])->url
  );
}

and then pass this array to my view

$viewData["images"] = $images;
$content = renderView("project", $viewData);

and in the view file, I iterate through $images array

          <div class="project__images">
            <div class="project__images-row" data-lightgallery>
              <?php foreach ($images as $image): ?>
                <div class="project__image-box">
                  <a class="project__image-link" data-lightgallery-item href="<?= $image["large"]; ?>" title="<?= $image["desc"]; ?>">
                    <img class="project__image" src="<?= $image["thumb"]; ?>" alt="<?= $image["desc"]; ?>">
                  </a>
                </div>
              <?php endforeach; ?>
            </div>
          </div>
        <?php endif; ?>

So I do for all complex and simple fields.

I like this approach, but I have feelings that I overcomplicate things because I can just simply pass $page->images to view and iterate through this WireArray. 

So my questions are: 

Due to this approach, I need to iterate several times to output just one field, does it influence performance ( in a case of some complex repeater field)?  

What do you think about it?

Should I do it in the way I do or just pass WireArray?

Maybe you can share your vision and approach about it.

P.S. I know that my questions look a little bit dumb. :-[

Link to comment
Share on other sites

I am following a similar approach, but I don't reduce objects to simpler states, I just pass them along to partial templates and use PW specific properties. Your approach is more portable with better separation, but unless you're thinking of migrating your code/template to other systems, where you'll be passing around arrays with same set of same keys, it doesn't make much difference. And not mapping objects to arrays presumably reduces process time/RAM usage as well.

I think of my partial templates as components. Although much of hard work is abstracted away from them inside actual template files, components have specific functions available to them. Here's my navigation

# Navigation is defined in YAML
Blog:
    href: /blog/
    class: highlight

Labs:
    href: /labs/

Works:
    href: /works/

GitHub:
    href: https://github.com/abdusco
    target: _blank

and here's its partial

<?php namespace Processwire;
/* @var $links WireArray */
$linkList = [];

if (!function_exists('renderLinks')) {
    function renderLinks($links, $linkClass)
    {
        $out = [];
        foreach ($links as $name => $attrs) {
            if(page()->path === $attrs['href']) continue;
            $anchor = '';
            // generate attributes string
            $attrs = $links[$name];
            $class = $attrs['class'] ?? '';
            $attrs['class'] = $class . $linkClass;
            foreach ($attrs as $attr => $val) $anchor  .= " $attr='$val'";

            $anchor = "<a $anchor>$name</a>";
            $out[] = $anchor;
        }
        return $out;
    }
}

?>
<nav class="pad t--bold">
    <?php foreach (renderLinks($links, 'footer-nav__link pad inline-block link link--b-no') as $link) echo $link; ?>
</nav>

Since I'll be passing the same YAML array, and not use renderLinks anywhere else, I keep them inside my partial.

If I need to use this navigation elsewhere, I'd probably abstract link class (footer-nav__link) as a parameter I pass inside wireRenderFile, or refactor that class into a more general one.

  • Like 1
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...