Namek Dev
a developer's log
NamekDev

Caching Partial View with View Composer in Laravel

September 27, 2014

Laravel 4 has got pretty nice Cache mechanism. Unfortunately, it’s nicety brings not too much functionality. It lacks a way to cache whole pages or partials.I have found nice plugin called Flatten which works on top of Laravel Cache and is able to do the job. What I desired was to cache partial view and also cache it’s data being created by View Composer.

My partial view is called menu. I aggregate product categories from ElasticSearch database to just present them in this menu. So I want to avoid two things:

  1. category aggregation from database
  2. creation of menu template

Having my view:

@cache('menu', 10)
<ul>
@foreach ($categories as $category)
    <li>{{ $category['name'] }}</li>
@endforeach
</ul>
@endcache

I want to access categories only when Flatten does not have valid cache for this partial (cache is for 10 minutes).

For this I create View Composer:

class MenuPartialComposer {
    public function compose($view) {
        $categories = ESProducts::aggregateCategories();
        $view->with('categories', $categories);
    }
}

Unfortunately, Laravel launches view composer every time it hits partial creation during View::make() call. To prevent from database aggregation I dig into the Flatten code and did the following:

class MenuPartialComposer {
    public function compose($view) {
        if (Cache::has('flatten-section-menu')) {
            return;
        }

        // do the rest here
    }
}

So the final result is that I cache the view but I do not do the same with aggregated data.Instead I just avoid aggregation when partial is already cached. I believe this solution is just a workaround but I couldn’t find better way without modifying the library. Certainly, it would be better to Flatten having API designed for such case.

php
comments powered by Disqus