# SoberWP Controller: ACF loops and static functions

**URL:** https://discourse.roots.io/t/soberwp-controller-acf-loops-and-static-functions/10345
**Category:** sage
**Tags:** sage9
**Created:** 2017-09-02T18:19:43Z
**Posts:** 9

## Post 1 by @patram1121 — 2017-09-02T18:19:43Z

Using Sage9 beta 4 and ACF.

Based on the helpful info from @withjacoby in the post [SoberWP Controller: Access $post objects data from archive page](https://discourse.roots.io/t/soberwp-controller-access-post-objects-data-from-archive-page/9478/2),

I know when I have a blade template with something like:

```
@while( have_rows('repeater') ) @php( the_row() )
    @if ( SampleController::controllerFunctionWithSubFields() )
        {{ get_sub_field('content') }}
  @endif
```

The function in the controller should be static:

```
public static function controllerFunctionWithSubFields()
  {
    return get_sub_field('criteria1') && get_sub_field('criteria2');
  }
```

But wanted to understand why: If a function is not static in a controller, is it only “run” when the controller is created? Or is something else going on?

---

## Post 2 by @withjacoby — 2017-09-02T23:21:42Z

Public functions are converted to variables, whereas public static functions are exposed to the view as functions, useful for loops.

Let me know if that helps answer the question?

---

## Post 3 by @patram1121 — 2017-09-03T00:00:37Z

Thx for the message. Sorry if I’m being a bit slow but I wanted to understand.

When are the controller public functions converted into variables? Before any of the Blade code is run?

---

## Post 4 by @Webstractions — 2017-10-13T20:12:20Z

@withjacoby T’would be nice if all data fell under one blanket function like `_data()` and you did all your variable declarations there. Having to do individual (non-static) functions just to declare variables is tedious. It is also confusing when you start mixing them with static functions.

I would like to see something like this within a controller:

```
public function _data() {
    
    $item = [
       // get some data from external class
    ];
    $title = $this->transform( get_the title() );
    $another_var = function() {
        // do some more stuff here
   }

  return compact( 'item', 'title', 'another_var');
}
```

Now you have a very clear, simple, and easier to read function for your variables. Using functions just to declare variables is counter-intuitive. A lot of people are getting hung up on this (I know I did).

EDIT: I put in a request to add this functionality [#52 Sober Controller](https://github.com/soberwp/controller/issues/52)

---

## Post 5 by @Nicolo_Sacchi — 2017-10-15T23:20:23Z

I see your point but in my experience, this would end up into being a monster method which holds far too much logic in one place. I think this boils down to a personal preference to be honest, everyone has a different mindset when developing but I usually prefer to have many small and testable functions more than just one gigantic one.  
Either way I agree it would be super nice to have some extra goodies from `controller` to be able to manipulate/organise data in different ways. I really like your idea of a `transform` method that could be used to standardise output! :slight_smile:

---

## Post 6 by @MWDelaney — 2017-10-15T23:36:02Z

I like the current method because I can set simple variables like `$featuredimagesize` in multiple contexts for different post types and use the same template! Super convenient.

---

## Post 7 by @Webstractions — 2017-10-16T12:14:05Z

@Nicolo_Sacchi Transformers come in pretty handy in some cases, such as @MWDelaney with `$featuredImageSize`.

On the flip-side of smaller methods, you soon have a monster controller. Might be a case for using `traits` here, just to keep common sets of values together. Won’t reduce the size of the controller, but will clean it up a bit.

---

## Post 8 by @Nicolo_Sacchi — 2017-10-16T21:40:23Z

Personally, I wrote my own framework so that I can use models and use the whole MVC stack while developing. This way I delegate most of the heavy stuff to the models, organise what I want to expose in a few methods in my controller and keep my templates nice and clean :slight_smile: Having models makes life so much easier!

---

## Post 9 by @Webstractions — 2017-10-20T13:54:04Z

Ah. I see. Makes sense.

I been trying to use View Composers in lieu of models. They have event listeners that I can see registered in the service container, but they are not firing. Not sure what to make of that.

Premise is simple. Create a composer with the data you want to pass.

```
<?php

namespace App\Composers;

use Illuminate\View\View;

class AcfObjectsComposer {

  public function compose(View $view)
  {
     $view->with('acfObjects', get_field_objects());
  }

}
```

This will create an `$acfObjects` variable for a view to use. As you can see, it uses ACF’s `get_field_objects()` function. That variable can now be used for loops normally.

Specifying a view or views for that composer via a service provider

```
<?php

namespace App\Providers;

use App\Providers\AbstractProvider;

class ViewComposerProvider extends AbstractProvider {

  public function register()
  {
     \App\sage('view')->composer(['content.single', 'single'], '\App\Composers\AcfObjectComposer');
  }
}
```

I bind this provider to the Sage Container, and as I said, it actually creates the event listeners, but they don’t fire – or something else is going on.
