Passing default data for a controller in Laravel - php

I want to build a menu from an array in Laravel. What I'm currently doing is putting the array in a view
$menu = ['home', 'users' => ['create users' , 'update user', 'activity log']];
and then looping through it to generate the menu:
<section>
<!-- Left Nav Section -->
<ul class="left">
<li class="divider"></li>
#foreach($menu as $key => $nav)
<li class="has-dropdown">
{{ $key }}
<ul class="dropdown">
#foreach($nav as $subnav)
<li>
{{ $subnav }}
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
</section>
Is there any other way that I can achieve the same result without putting the data in the view?
I also tried creating a constructor function in the controller:
public function __construct() {
$menu = ['home', 'users' => ['create users' , 'update user', 'activity log']];
return $menu;
}
But I guess that is not how it works. I appreciate any ideas on how I can go about this. Thanks in advance

View composers to the rescue!
They are executed every time before a view is rendered, so you can use this to pass standard data to them.

If you're using controller layouts you can bind data to the layout from within the constructor. Just make sure you call the parent constructor first so that the layout is instantiated properly.
public function __construct()
{
parent::__construct();
$this->layout->menu = ['home', 'users' => ['create users' , 'update user', 'activity log']];
}
That will bind a $menu variable to the layout, and will also be available to any nested views that are used with Blades #include.

Have a look at view composers:
http://www.laravel.com/docs/views#view-composers

Related

Laravel linking using controller

see this apple icons, these are rendering from foreach loop in view, defined variable in controller . i can change each icons but not able to assign link to each icon.
Hello guys i am stuck in linking using laravel controller.
my code is something like that: (i have a service page which has sub services page there is only one view which is using controller variable to showing data. i want each page button have different links. links can be static so i can putt it from controller. dont have any database attached to this solution. i want each href as a separate link)
This is view:
<?php $index=-1; ?>
#foreach ($third_fold_3_technologies_list as $item)
<?php $index++; ?>
<span class="{{ $item }}"></span>
#endforeach
This is controller:
$third_fold_3_technologies_list = [
'icon-appleinc',
'icon-appleinc',
'icon-appleinc',
];
You can use associative array.
$third_fold_3_technologies_list = [
'http://<link1>' => 'icon-appleinc',
'/<link2>' => 'icon-appleinc',
'<link3>' => 'icon-appleinc',
];
Then in your view
#foreach ($third_fold_3_technologies_list as $link => $class)
<span class="{{ $class }}"></span>
#endforeach

Laravel get current route

I have some navigation links and I want to get the current route in laravel 5 so that I can use the class active in my navigations. Here are the sample links:
<li class="active"> Home </li>
<li> Contact </li>
<li> About </li>
As you can see, in the Home link there is the active class which means that it is the current selected route. But since I am using laravel blade so that I would not repeat every navigation links in my blades, I can't use the active class because I only have the navigation links in my template.blade.php. How can I possibly get the current route and check if it is equal to the current link? Thank you in advance.
$uri = Request::path()
Check out the docs
You can use named routes like
Route::get('/', ['as'=>'home', 'uses'=>'PagesController#index']);
and then in the view you can do the following
<li {!! (Route::is('home') ? 'class="active"' : '') !!}>
{!! link_to_route('home', 'Home') !!}
</li>
So I got it working with some little tricks. For example the url in the address bar is http://localhost:8000/tourism/places.
If I will use the Request::path() method, I will get tourism/places. But what I wanted to get is the tourism part only so what I did is this:
$currentPath = Request::path();
$values = explode("/", $currentPath);
$final = $values[0];
Now the $final variable will have the value "tourism".
Now to make the variable load globally, I included the code in the AppServiceProvider.php inside the public function boot().
public function boot()
{
$currentPath = Request::path();
$values = explode("/", $currentPath);
$final = $values[0];
view()->share('final', $final);
}
And lastly in my blade template,
<li #if ($final== "tourism") class="active" #endif>
Places
</li>
Simple way is always better, just use the same function you use to generate links and it will give you all, including the flexibility to use wild cards
<a class="nav-link {{ Request::url() === route("products.list", [$group_key]) ? 'active' : '' }}"
href="{{ route("products.list", [$group_key]) }}"
>
LInk text
</a>
Plus, you still are going to have only one place to manage URL-s - your router files.

Building an ecommerce site using Laravel: How do I view/route products based on their ID?

I followed a tutorial on Tutsplus about creating an ecommerce website using Laravel. The problem I'm having right now is when trying to route to a subfolder. In the tutorial, the instructor included a feature where you can view products by ID. And this is how he did it:
// StoreController.php
public function getView($id) {
return View::make('store.view')->with('store', Store::find($id));
}
This piece of code seems to be passing an id from the stores table. I think when a product is clicked, that's when the id is passed
// Routes.php
Route::controller('store', 'StoreController');
Also some of the templates:
// store\index.blade.php
<h2>Stores</h2>
<hr>
<div id="stores row">
#foreach($stores as $store)
<div class="stores col-md-3">
<a href="/store/products/view/{{ $store->id }}">
{{ HTML::image($store->image, $store->title, array('class' => 'feature', 'width'=>'240', 'height' => '127')) }}
</a>
<h3>{{ $store->title }}</h3>
<p>{{ $store->description }}</p>
</div>
#endforeach
</div><!-- end product -->
So.. How it goes is when I click on a product, it leads me to domain:8000/store/view/6 where 6 is the id.
This works fine but what I want to know is how do I route through a subfolder? Let's say I want it to be like this: store/view/products/6 considering that I have a folder called products and my view.blade.php is inside that like this: store/products/view.
In my StoreController class, I tried changing this
public function getView($id) {
return View::make('store.view')->with('store', Store::find($id));
}
to this
public function getView($id) {
return View::make('store.product.view')->with('store', Store::find($id));
}
but it does not seem to work giving me nothing but a Controller Method Not Found Error.
First, the view name View::make('store.product.view') has nothing to do with the URL.
You have to change the route:
Route::controller('store/view', 'StoreController');
And then adjust the name of your method in the controller because it should be the same as the segment of the URL after store/view
public function getProducts($id) {
return View::make('store.product.view')->with('store', Store::find($id));
}
I strongly recommend you read the Laravel docs on the topic

How to include a controller method's view as a part of another controller view in Laravel PHP Framework

Halo here is my need;
i want to include different view as apart of different view in laravel php frame work.
class DashboardController extends BaseController {
public function comments( $level_1=''){
// process data according to $lavel_1
return View::make('dashboard.comments', $array_of_all_comments);
}
public function replys( $level_2=''){
// process data according to $lavel_1
return View::make('dashboard.replys', $array_of_all_replys);
}
these both data can now accessed from
www.abc.com/dashboard/comments
www.abc.com/dashboard/replys
And in my view what i need is to generate replys according to the comments id ($lavel_2)
// dashboard/comments.blade.php
#extends('layout.main')
#section('content')
#foreach($array_of_all_comments as $comment)
comment {{ $comment->data }},
//here is what i need to load reply according to the current data;
//need to do something like this below
#include('dashboard.replys', $comment->lavel_2) //<--just for demo
.................
#stop
and in replys also got
#extends('layout.main')
#section('content')
// dashboard/replys.blade.php
#foreach($array_of_all_replys as $reply)
You got a reply {{ $reply->data }},
...........
#stop
is there any way i can achieve this on laravel 4?
Please help me i wanted to load both comments and replays in one go and later need to access them individually via ajax also
please help me thank you very much in advance
halo i found the solution here
all we need is to use App::make('DashboardController')->reply();
and remove all #extends and #sections from including view file
the change are like this
// dashboard/comments.blade.php
#extends('layout.main')
#section('content')
#foreach($array_of_all_comments as $comment)
comment {{ $comment->data }},
//<-- here is the hack to include them
{{-- */echo App::make('DashboardController')->reply($comment->lavel_2);/* --}}
.................
#stop
.............
and in replys is now changed to
// dashboard/replys.blade.php
#foreach($array_of_all_replys as $reply)
You got a reply {{ $reply->data }},
...........
#endforeach
-------------
thanks
You probably want to rework your views and normalise your data. Comments and replies are (probably) the same.
If you make a Comment model which belongsTo "parent" (another Comment model) and hasMany "children" (many Comment models), then simply set parent_id to 0 for a top-level Comment, and set it to the ID of another Comment to make it a Reply.
Then your Blade views do something like:
comments.blade.php
#foreach ($comments AS $comment)
#include( 'comment', [ 'comment' => $comment ] )
#endforeach
comment.blade.php
<div>
<p>{{{ $comment->message }}}</p>
#if( $comment->children->count() )
<ul>
#foreach( $comment->children AS $comment )
<li>
#include( 'comment', [ 'comment' => $comment ] )
</li>
#endforeach
</ul>
#endif
</div>

blade templates recursive includes

I have an array of items that represent the file and dir structure of a directory on the server.
The $items array is constructed like this:
Array
(
[folder1] => Array
(
[folder1_1] => Array
(
[0] => filenameX.txt
[1] => filenameY.txt
)
)
[pages] => Array
(
)
[0] => filename.txt
[1] => filename1.txt
)
what we want, is essentially <ul> with <li> for every node.
the resulting HTML should be something like
folder1/
folder1_1/
filenameX.txt
filenameY.txt
pages/
filename_1.txt
filename_2.txt
Now, my question has to do with nested includes with laravel's blade templating engine.
I have a view list.blade.php with the following contents
<div class="listing">
#include('submenu', array('items', $items))
</div>
and I pass it the array like this:
View::make('list')->with('items', $items)
the included template (submenu.blade.php) has the following:
<ul>
#foreach($items as $key=>$value)
#if (is_array($value))
<li>{{$key}}/
#include('submenu', array('items', $value))
</li>
#else
<li>{{$value}}</li>
#endif
#endforeach
</ul>
I #include the same template from within itself but with the new data, in case the $value is an array (directory)
First of all, is this at all possible?
If not, is there another way to achive the desired result?
TIA,
Yes, this is indeed possible.
However, there's an issue in your includes, you have:
#include('submenu', array('items', $value))
It should be:
#include('submenu', array('items' => $value))
It's worth noting also another hidden blade statment, #each. You can use this instead of looping through the array yourself, something like this:
<ul>
#each('item.detail', $items, 'item')
</ul>
Then you create a new blade file named item.detail and pop what you previously had in your loop in that file. It helps to clean up your view from having more and more nested loops.
The data for the item when you are inside your new blade file will be held in the third parameter, in this case $item
Instead of using array, use an eloquent collection. Instead of using #include, use \View::make. It cleans up the code a bit. Here is an example drop down menu for the Foundation 5 framework, using an eloquent model with parent/child relationship:
My model has a parent->child relationship
public function children() {
return $this->hasMany('Category', 'parent_id');
}
I generate my results like so in my controller
$categories = \Category::where('parent_id', '=', '0')->with('children')->get();
Blade template: _partials.dd-menu.blade.php
<ul class="{{$class}}">
#foreach($items as $item)
<?php
$active = $item->id == \Input::get('category') ? 'active' : '';
$hdd = $item->children->count() ? 'has-dropdown' : '';
?>
<li class="{{$hdd}} {{$active}}">
{{$item->name}}
#if ($item->children->count())
{{ View::make('_partials.dd-menu')->withItems($item->children)->withClass('dropdown')}}
#endif
</li>
#endforeach
In your parent blade:
<nav class="top-bar" data-topbar role="navigation">
<ul class="title-area">
<li class="name">
<h1>Categories</h1>
</li>
<!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone -->
<li class="toggle-topbar menu-icon"><span>Menu</span></li>
</ul>
<section class="top-bar-section">
<!-- Right Nav Section -->
{{ View::make('_partials.dd-menu')->withItems($categories)->withClass('right')}}
</section>
</nav>

Categories