I am facing a problem where I don't want to display an X element in some views.
The real example is that I don't want to show product image slider on pages contact
and about us
, but it should be visible on all other pages (about 6 more)
So how to exclude rendering the div in n of m pages without making very long @if
conditions?
Any idea for stylish solution?
Edit
Answering the question why I don't want to put this in standalone view file:
Imagine that you want this line to be visible in all views your views except specific one, and only one
<span>Lorem Ipsum</span>
This is just a single line of HTML code, it's not worth to create another file in project because it will be a mess in project files tree, and another example that is a bad workaround
@if(\Request::route()->getName() !== "some.very.long.route.alias.name.that.looks.ugly")
<span>Lorem Ipsum</span>
@endif
Makes code hard to read and understand when project grows
Edit 2
I predicted some of suggested solutions and already wrote why this is not suitable way to handle this. I am looking more likely for a solution that is similar to @can
or @cannot
that depends on current route
Edit 3: Working on solution
Edit 4: I posted an answer here but it's not perfect yet (I won't mark it as accepted yet), so just for readers of this topic I will paste the copy of it below
Ok I have made a simple blade directive that solves this case in a well-looking way
At first, create an array that determines route access for html snippet
Best place would be to create this file in config directory, on example apresence.php
file<?php return [ 'ipsum' => [ // presence alias 'about', // disallowed route #1 'contact' // disallowed route #2 ], ];
Then create a directive in
AppServiceProvider.php
class<?php namespace App\Providers; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Blade::directive('presence', function($alias) { return "<?php if (in_array(\Request::route()->getName(),config('presence.'.$alias))):?>"; }); Blade::directive('endpresence', function() { return '<?php endif; ?>'; }); } /** * Register any application services. * * @return void */ public function register() { // } }
And in the final usage of this trick in html view
@presence('ipsum') <span>Lorem Ipsum</span> @endpresence
It will print
Lorem Ipsum
if the current route name is not inipsum
array (which is declared in\App\config\presence.php
file so we can access it withconfig()
helper method)It would be great if I could handle wildcard characters, like
<?php return [ 'ipsum' => [ // presence alias 'admin.category.*', // advanced route pattern #1 'admin.users.*' // advanced route pattern #2 ], ];
But I will look into it later.
Feedback, or criticism is always welcome :)
If contact
and about us
have their own URIs, you can try to match on that to determine if you should show the element of not...
if (!\Request::is('contact') && !\Request::is('about-us')) {
// Show element X
}
Or another way to do it would be to add a middleware which sets some variable, for example $dontShowElement
and sets up a view composer and passes that variable to all views. Then all you need to do is check for the existence of that variable before outputting the element and only give those 2 routes you want that element to be hidden on that middleware.
If you are using blade templating, you could create two different layouts. One with the image slider and one without. This is the most straightforward solution I can think up from the top of my head.
EDIT: Creating another layout, especially if you have all your layouts in a separate folder, will not create a mess in the file structure and it will definitely be worth it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With