{"id":15293887,"url":"https://github.com/bhushan/stash-view","last_synced_at":"2025-04-13T13:31:48.920Z","repository":{"id":47740254,"uuid":"282390171","full_name":"bhushan/Stash-View","owner":"bhushan","description":"Stash view is a composer package for Laravel which caches blade views using Russian Doll Caching methodology. Which drastically improves speed of the website and as a side effect reduces sql queries and solves n+1 problem.","archived":false,"fork":false,"pushed_at":"2021-08-15T19:49:00.000Z","size":137,"stargazers_count":21,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T04:51:24.535Z","etag":null,"topics":["blade","cache","laravel-framework","memcached","php","redis","speed"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bhushan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-25T07:01:09.000Z","updated_at":"2025-03-26T15:53:06.000Z","dependencies_parsed_at":"2022-08-21T11:20:58.260Z","dependency_job_id":null,"html_url":"https://github.com/bhushan/Stash-View","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhushan%2FStash-View","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhushan%2FStash-View/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhushan%2FStash-View/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhushan%2FStash-View/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bhushan","download_url":"https://codeload.github.com/bhushan/Stash-View/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248721131,"owners_count":21151050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blade","cache","laravel-framework","memcached","php","redis","speed"],"created_at":"2024-09-30T16:53:35.507Z","updated_at":"2025-04-13T13:31:43.894Z","avatar_url":"https://github.com/bhushan.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stash View\n\nStash view is a composer package for `Laravel` which caches views using Russian Doll Caching methodology.\n\n\u003e What is Russian Doll Caching ?\n\u003e It is really famous caching stratergy to cache your views into small chunks. It is quite famous in Rails community. If you are interested to know more checkout this [link](https://guides.rubyonrails.org/caching_with_rails.html).\n\nIn a nutshell, It caches your views into chunks.\nThis article will give you more clear [idea](https://signalvnoise.com/posts/3112-how-basecamp-next-got-to-be-so-damn-fast-without-using-much-client-side-ui).\n\n![Russian Doll Caching PNG](http://s3.amazonaws.com/37assets/svn/777-russian-doll-caching-1.png)\n\n## Now enough about idea let's talk about how to use it\n\n\u003e You can also checkout example code from [here](https://github.com/bhushan/Stash-View-Example)\n\n\u003e Want video explaination of internals? check this [youtube](https://www.youtube.com/watch?v=iNWCCYs0qKs) link. \n\n## Installation\n\n### Step 1: Composer\n\nFirstly require this package using following command.\n\n```bash\ncomposer require enlight/stash-view\n```\n\n### Step 2: Service Provider (Optional)\n\n This package supports auto discovery but if you are using `Laravel 5.4` or below you need to add `ServiceProvider` into `providers` array.\n\nFor your Laravel app, open `config/app.php` and, within the `providers` array, append:\n\n```php\nEnlight\\StashView\\Providers\\StashViewServiceProvider::class\n```\n\nThis will bootstrap the package into Laravel.\n\n### Step 3: Cache Driver\n\nFor this package to function properly, you must use a Laravel cache driver that supports tagging (like `Cache::tags('foo')`). Drivers such as `Memcached` and `Redis` support this feature.\n\nCheck your `.env` file, and ensure that your `CACHE_DRIVER` choice accomodates this requirement:\n\n```php\nCACHE_DRIVER=redis\n```\n\n\u003e NOTE: If your application is set to `local` environment then by default this package will use `array` caching driver to speed up development process so that you don't need to clear cache again and again while developing.\n\nHave a look at [Laravel's cache configuration documentation](https://laravel.com/docs/7.x/cache#configuration), if you need any help.\n\n## Usage\n\n### The Basics\n\nWith the package now installed, you may use the provided `@cache` Blade directive anywhere in your views, like so:\n\n```html\n@cache('my-cache-key')\n    \u003cdiv\u003e\n        \u003ch1\u003eHello World\u003c/h1\u003e\n    \u003c/div\u003e\n@endcache\n```\n\nBy surrounding this block of HTML with the `@cache` and `@endcache` directives, we're asking the package to cache the given HTML. Now this example is trivial, however, you can imagine a more complex view that includes various nested caches, as well as lazy-loaded relationship calls that trigger additional database queries. After the initial page load that caches the HTML fragment, each subsequent refresh will instead pull from the cache. As such, those additional database queries will never be executed. Really cool side effect of this package is it reduces you sql queries and solves n+1 problem out of the box.\n\nPlease keep in mind that, in production, this will cache the HTML fragment \"forever\". For local development, on the other hand, we are using `array` cache driver which stores the cache in memory and flush out when work done. That way, you may update your views and templates however you wish, without needing to worry about clearing the cache manually.\n\nNow because your production server will cache the fragments forever, you'll want to add a step to your deployment process that clears the relevant cache.\n\n```php\nCache::tags('views')-\u003eflush();\n```\n\n### Caching Models\n\nWhile you're free to hard-code any string for the cache key, the true power of Russian-Doll caching comes into play when we use a timestamp-based approach.\n\nConsider the following fragment:\n\n```html\n@cache($post)\n    \u003carticle\u003e\n        \u003ch2\u003e{{ $post-\u003etitle }}\u003e\u003c/h2\u003e\n        \u003cp\u003eWritten By: {{ $post-\u003eauthor-\u003eusername }}\u003c/p\u003e\n\n        \u003cdiv class=\"body\"\u003e{{ $post-\u003ebody }}\u003c/div\u003e\n    \u003c/article\u003e\n@endcache\n```\n\nIn this example, we're passing the `$post` object, itself, to the `@cache` directive - rather than a string. The package will then look for a `getCacheKey()` method on the model. We've already done that work for you; just have your Eloquent model use the `Enlight\\StashView\\Traits\\Cacheable` trait, like so:\n\n```php\nuse Enlight\\StashView\\Traits\\Cacheable;\n\nclass Post extends Eloquent\n{\n    use Cacheable;\n}\n```\n\nAlternatively, you may use this trait on a parent class that each of your Eloquent models extend.\n\nThat should do it! Now, the cache key for this fragment will include the object's `Primary Key` ie `id` in most cases and `updated_at` timestamp: `App\\Post/1-98765432101`.\n\n\u003e The key is that, because we factor the `updated_at` timestamp into the cache key, whenever you update the given post, the cache key will change. This will then, in effect, bust the cache!\n\n#### Touching\n\nIn order for this technique to work properly, it's vital that we have some mechanism to alert parent relationships (and subsequently bust parent caches) each time a model is updated. Here's a basic workflow:\n\n1. Model is updated in the database.\n2. Its `updated_at` timestamp is refreshed, triggering a new cache key for the instance.\n3. The model \"touches\" (or pings) its parent.\n4. The parent's `updated_at` timestamp, too, is updated, which busts its associated cache.\n5. Only the affected fragments re-render. All other cached items remain untouched.\n\nLuckily, Laravel offers this \"touch\" functionality out of the box. Consider a `Note` object that needs to alert its parent `Card` relationship each time an update occurs.\n\n```php\n\u003c?php\n\nnamespace App;\n\nuse Enlight\\StashView\\Traits\\Cacheable;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Note extends Model\n{\n    use Cacheable;\n\n    protected $touches = ['card'];\n\n    public function card()\n    {\n        return $this-\u003ebelongsTo(Card::class);\n    }\n}\n```\n\nNotice the `$touches = ['card']` portion. This instructs Laravel to ping the `card` relationship's timestamps each time the note is updated.\n\nNow, everything is in place. You might render your view, like so:\n\n\u003e resources/views/cards/_card.blade.php\n\n```html\n@cache($card)\n    \u003carticle class=\"Card\"\u003e\n        \u003ch2\u003e{{ $card-\u003etitle }}\u003c/h2\u003e\n\n        \u003cul\u003e\n            @foreach ($card-\u003enotes as $note)\n                @include ('cards/_note')\n            @endforeach\n        \u003c/ul\u003e\n    \u003c/article\u003e\n@endcache\n```\n\n\u003e resources/views/cards/_note.blade.php\n\n```html\n@cache($note)\n    \u003cli\u003e{{ $note-\u003ebody }}\u003c/li\u003e\n@endcache\n```\n\nNotice the Russian-Doll style cascading for our caches; that's the key. If any note is updated, its individual cache will clear - long with its parent - but any siblings will remain untouched.\n\n### Caching Collections\n\n\u003e Its not yet supported but this is already in todo list. Will appreciate any good PR for this. :)\n\n## FAQ\n\n**1. Is there any way to override the cache key for a model instance?**\n\nYes. Let's say you have:\n\n```html\n@cache($post)\n    \u003cdiv\u003eview here\u003c/div\u003e\n@endcache\n```\n\nBehind the scenes, we'll look for a `getCacheKey` method on the model. Now, as mentioned above, you can use the `Enlight\\StashView\\Traits\\Cacheable` trait to instantly import this functionality. Alternatively, you may pass your own cache key to the `@cache` directive, like this:\n\n```html\n@cache('post-pagination')\n    \u003cdiv\u003eview here\u003c/div\u003e\n@endcache\n```\n\nThis instructs the package to use `post-pagination` for the cache instead. This can be useful for pagination and other related tasks.\n\nThat's it. Thank You :)\n\nHappy Coding.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhushan%2Fstash-view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbhushan%2Fstash-view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhushan%2Fstash-view/lists"}