Laravel - how can make dynamic content with layout? - php

I'm wanting to create a website with laravel framework. I had made layout but now, have some zone i don't know how to set content for it. Ex: 2 zone of me are left-menu and cart (please view picture). My left-menu will get content from table: categories and cart will get content from package cart [Cart::content()].
It's on layout and of course, all page will have it. But i don't know how to give content of categories and cart() for it. Please help me

I think that you should to use View Composer.
https://laravel.com/docs/5.6/views#view-composers

Use Blade templates, as found here: https://laravel.com/docs/5.6/blade
Wherever in your page you want to print content, use the {{ $mycontent }} construct. You can also use confitionals and loop structures like #if and #foreach to loop through collections.
Then, in your controllers, you can just call the view and pass it content from your database or wherever you get it by doing something like:
return response()->view(“myView”, [“mycontent” => $content], $httpStatus);

You may opt for afterMiddleware if you want it on every page. Create a section on the master blade page (usually app.blade.php) and fill it in the middleware just like you would in any other controller. You can create a middleware by running php artisan create:middleware Cart. A file will be created at app/Http/Middleware/Cart.php.
Register the middleware in the app/Http/kernel.php file.
You may have to add a Auth::check() condition to avoid errors.

Related

Adding information to a Layout without having to call it on every controller

I have a layout that is used when you are logged in. menu.blade.php.
Then I use it in blade files #extends('admin.layouts.menu')
I want to show some information in the layout, let's say the number of messages near the "message" link in the menu. I could easily do this by adding:
$message_count = Message::where("user_id", Auth::user()->id)->count();
and adding: <div>{{$message_count}}</div> to menu.blade.php
to every single controller and view where the layout is used, but this is clearly not a clean way to do it.
Is there a way to pass information to the view in a single step instead of having to do it in every single controller?
Use view composers.
View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location
Register the view composer within a service provider:
public function boot()
{
View::composer('menu', function ($view) {
$view->with('messagesCount', auth()->user()->messages->count())
});
}
Then each time when the menu view will be rendered, it will have $messagesCount variable with counted messages for an authenticated user.

web middleware for specific routes in laravel 5.2

In Laravel 5.4 the web middleware is included on all routes by default. But I want to show those routes(menu's) assign to users. For example
I have some routes(menu's) as follows
user\list
user\add
user\show_form
list\forms
if user 'ABC' assign only two routes(menu's) like
`user\list`
`user\add`
so when user 'ABC' is logged that in menu shows only two routes(menu's) those assign. When user create that time I assign routes(menu's) and this stored in permission table. Now my question is how can I handle this using middleware.
Is this possible handle via middleware. please suggest me
Thanks in advance
Since you are pulling from the database, what I would do is skip the middleware idea all together and approach this by querying the user's routes and then displaying them on the page. I would accomplish this by using a service provider.
Let's assume you have your project set up with a user-navigation.blade.php file which contains your user's nav elements. Maybe something like:
<ul class="side-nav">
<li>
List
</li>
<li>
Add
</li>
</ul>
And you are bringing that file into your other blade template with #include('user-navigation').
What we want to do is do a query for the current user's routes ANY time that view (user-navigation) is displayed to the user. We can do this easily with a service provider.
Run the following command in your terminal: php artisan make:provider UserNavigationServiceProvider. Next, we need to tell Laravel to actually use this service provider. Open config/app.php and scroll down to the area where it says 'Application Service Providers' and add this: App\Providers\UserNavigationServiceProvider::class,. Now edit the file found in app\Providers\UserNavigationServiceProvider.php
If you're using Laravel's default Authentication, bring it in at the top of your file: use Auth;. We also need to bring in the model for your permissions table. So put use App\Permission; at the top of this file as well.
Now, in the boot() method, make it look like this:
public function boot()
{
$this->getUserNavigation();
}
Next, we're going to create the getUserNavigation() method. Just below the register() method, add this:
private function getUserNavigation()
{
view()->composer('user-navigation', function($view)
{
$userID = Auth::id();
$userNavigation = ! is_null($userID) ? Provider::where('user_id', $userID)->get() : null;
$view->with([ 'userNavigation' => $userNavigation ]);
});
}
So lets break down what we're doing in this new method. First, we're saying we want to target the view by the name of user-navigation. Any time this view is loaded we're going to perform the logic in this closure. Next, we use the default Laravel Auth way to obtain the current user's ID, then we run a query on the permissions table using Eloquent. NOTE: I am assuming you have a column in your permissions table that is user_id. This query gives us a collection of all the records owned by that user in the permissions table. Now we're binding that result to the variable $userNavigation and passing it to user-navigation as $userNavigation. NOTE: Because you are including user-navigation.blade.php in another file, that file will also have access to this $userNavigation variable.
Now, in user-navigation.blade.php lets write the logic. First we check to see if that variable is null. You can optionally skip this if you know a non-logged in user will never access this view. Then simply loop through it and display the results.
#if ( $userNavigation )
<ul class="side-nav">
#foreach( $userNavigation as $navItem )
<li>
{{ $navItem->url_name }}
</li>
#endforeach
</ul>
#endif
In the above example I am assuming you have a database column called url where you are storing the link and a column called url_name where you are storing the text for the anchor link. If not, you might consider adding those.
And that's it. You can use a service provider to give your view file(s) access to certain data any time they are used.
Hope this helps.

Add custom class to main blade template

My app.blade.php file is my main file that will #yield all my other blade template files. I noticed that the Auth class is available to this file. I cant figure out how to add one of my custom classes, Projects so it is available to app.blade.php.
app.blade.php contains a drop down menu where I need to list all my projects, but if I try something like
Projects::where('user_id','=',Auth::user()->id)->get()
I get an error saying the Projects class is not found. How can I add this to my master template just like how Auth is available? Or, do I need to go about this differently?
You do it by injecting the class into your template.
#inject('project', 'App\Project')
{{ $project->where('user_id','=',Auth::user()->id)->get() }}
Just make sure your namespace is correct.
http://laravel.com/docs/5.1/blade#service-injection

Laravel - How to NOT use a layout

I'm using laravel with controllers layout. But there are some parts of my app where I don't want to use a layout (for example, when returning data to the payment gateway request, for wich I send XML data). I just want to pass data to my view and render it alone, with no need for a layout.
How can I do that? I've been trying some approaches but none worked for this. I can successfuly change what layout to render, but I can't set to render the view without a layout.
Thanks!
Edit: Let me explain it better
My default layout is set in Base_Controller. Then all my controllers extends it but in one of them I need no layout, as I told above. Maybe I need to unset the default layout or something like that, I'm not sure.
You can simply return something from your controller action to bypass the layout.
function get_xml($id) {
$user = User::find($id);
return View::make('user.xml', $user);
}
On your controller functions, you can simply return a string, which will be thrown back to the browser as-is. Alternatively, you can craft a Laravel\Response object, which will allow you to fine-tune your site's output a lot more than just returning a string.
The Response class has a few tricks up its sleeve that are not mentioned on the docs: default return, JSON, forced download.
You're more interested in the first one, which will allow you to correctly set the content-type of the response to application/xml. In addition to this, you can still use views for XML! Generate the view as you would with View::make, but instead of directly returning it, store it in a variable. To render it, call render() on it - it will return the output.
A simple way....
suppose there is a main layout
<body>
#yield('content')
</body>
This content will be where the view will be inserted.
Now,
if you want to use layout, Make the view page like this:
#layout('main')
#section('content')
blah blah your content
#endsection
If you don't want to use layout, omit the codes above.
In controller, the code will be same for both the files.
return View::make('index');

Injecting random variable into every View in Laravel

I am just getting started with Laravel and working on porting a mess of a site to the framework.
One feature of the site is a dynamically added image in the header. I am using a common Blade template and was wondering if there is any way to inject a random variable (an integer between 1 and 4 would do) into every View that uses that layout.
What I would like to do is to be able to add something like so in the the common template-
<img src="img/cutouts/cutout-<?= $randomInt;?>.jpg" alt=""/>
with $randomInt sent to every View
You could look into View composers
So you would have something like:
View::composer('your.view', function($view)
{
$view->with('randomInt', rand(1,4));
}
That will pass the $randomInt variable in everytime you use the 'your.view' (or whatever) View.
It's also possible to add a variable to all views through View::share().
For example, you could modify the __construct method in Base_Controller with:
View::share('randomInt', rand(1,4));

Categories