hello to all I want to pass multiple variables to one view
this is my CategoryController.php
public function site()
{
$categories = Category::all();
return view('template.sitemap', ['categories' => $categories]);
}
and this is SubCategoryController.php
public function index2(){
$subcategories = SubCategory::all();
return view('template.sitemap',['subcategories'=>$subcategories]);
}
this is my route for this action in web.php
Route::get('sitemap.html','CategoryController#site')->name('sitemap')
Route::get('sitemap.html','SubCategoryController#index2')->name('sitemap');
and this is the view i am trying to do this sitemap.blade.php
#foreach($categories as $category)
<li>{{$category->name}}</li>
<ul>
#foreach($subcategories as $subcategory)
<li><a href="category.html">{{$subcategory->category_name->name}</li>
#endforeach
</ul>
#endforeach
but i constantly see undefind vairalble
alone they work good
but when i want user both variables seee undefined vairable.
Your site will go to the first route and will never go to your second controller.
You should rather write.
Route
Route::get('sitemap.html','CategoryController#site')->name('sitemap');
Controller
public function site(){
$data = array();
$data['subcategories'] = SubCategory::all();
$data['categories'] = Category::all();
return view('template.sitemap',compact("data"));
}
View
#foreach($data['categories'] as $category)
<li>{{$category->name}}</li>
<ul>
#foreach($data['subcategories'] as $subcategory)
<li><a href="category.html">{{$subcategory->category_name->name}}</li>
#endforeach
</ul>
#endforeach
you can write
public function site()
{
$categories = Category::all();
$subcategories = SubCategory::all();
return view('template.sitemap', compact('categories', 'subcategories');
}
or you can eager load this
public function site()
{
$categories = Category::with('subcategories')->get();
return view('template.sitemap', compact('categories');
}
in view
#foreach($categories as $category)
<li>{{$category->name}}</li>
<ul>
#foreach($category->subcategories as $subcategory)
<li><a href="category.html">{{$subcategory->name}}</li>
#endforeach
</ul>
#endforeach
Related
The code runs fine without the #foreach statement. When it's added I get the following error:
Undefined variable: articles (View: C:\laravel\laravel\resources\views\about.blade.php)
$articles is undefined.
Make the variable optional in the blade template. Replace {{ $articles }} with {{ $articles ?? '' }}
When I add the ?? '' it creates the error:
Facade\Ignition\Exceptions\ViewException
Invalid argument supplied for foreach()
Here is the complete code for the more daring:
https://github.com/matthoek/Articles
This is my view:
<? if (is_array($articles) || is_object($articles)) ?>
{
#foreach ($articles ?? '' as $article)
{
<li class = "first">
<h3>{{ $article->title}}</h3>
<p>{{ $article->excerpt }}</p>
</li>
#endforeach
}
}
</ul>
This is my controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Article;
class ArticlesController extends Controller
{
public function index()
{
$articles = App/Article::latest()->get();
//$articles = Review::all();
//$article = Review::all();
return view('articles.index',['articles'=>$articles]);
//return view('articles.index', ['articles' => $articles]);
}
public function show($id)
{
$article = App/Article::find($id);
//return view('articles.show', ['article' => $article]);
return view('articles.show')->with('article');
}
public function create()
{
return view('articles.create');
}
public function store()
{
//validation
//clean up
$article = new Article();
$article->title = request('title');
$article->excerpt = request('excerpt');
$article->body = request('body');
$article->save();
return redirect('/articles');
}
public function edit()
{
return view('articles.edit');
}
}
This is the section of my routes file web.php
Route::group(['middleware' => ['web']], function ()
{
Route::get('/about', function () {
$article = App\Article::latest()->get();
return view('about', compact('about', 'articles'));
//return $article;
});
}
I have changed the section of the routes file to the following but it did not seem to work.
return view('about')->with(['article'=> $article]);
I have made sure the following was in my app/Http/Kernel.php in middlewareGroups property for web
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
I have changed the foreach loop to an each loop and I get the same error on the line:
<h3>{{article->title}}</h3>
Let me know if I should post more code.
In your routes:
Route::get('/about', function () {
$articles = App\Article::latest()->get();
return view('about', compact('about', 'articles'));
});
It will return a collection, you can just loop it:
<ul>
#foreach ($articles as $article)
<li class = "first">
<h3>{{ $article->title}}</h3>
<p>{{ $article->excerpt }}</p>
</li>
#endforeach
</ul>
Update your view
<? if (is_array($articles) || is_object($articles)) ?>
{
#foreach($articles as $article)
<li class = "first">
<h3>{{ $article->title}}</h3>
<p>{{ $article->excerpt }}</p>
</li>
#endforeach
}
</ul>
the error is in you foreach loop: https://www.php.net/manual/en/control-structures.foreach.php
I have implemented printing a categories tree to the page recursively:
foreach ($categories as $category) {
$tree .='<li>'.$category->title.'';
if(count($category->childs)) {
$tree .=$this->childView($category);
}
}
$tree .='<ul>';
return view('categoryTreeview',compact('categories','allCategories','tree'));
}
public function childView($category){
$html ='<ul>';
foreach ($category->childs as $arr) {
if(count($arr->childs)){
$html .='<li>'.$arr->title.'';
$html.= $this->childView($arr);
}else{
$html .='<li>'.$arr->title.'';
$html .="</li>";
}
}
$html .="</ul>";
return $html;
}
For DB structure: id|title|parent_id
Now I need to implement a iterative way to print a category tree to the page, and so far I have not found a solution.
I also tried:
function buildTree($categories) {
$childs = array();
foreach($categories as $category)
$childs[$category->parent_id][] = $category;
foreach($categories as $category) if (isset($childs[$category->id]))
$category->childs = $childs[$category->id];
return $childs[0];
}
$treez = buildTree($categories);
But I also don't know how to use this data non-recursively.
Could anyone lead me on the right path? Maybe I should combine foreach loops with some kind of while condition?
In your category model:
public function subCategories()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
public function children()
{
return $this->subCategories()->with('children');
}
In your model:
public function getCategories()
{
$categories = Category::whereNull('parent_id')->with('children')->get();
return view('category', ['categories' => $categories]);
}
Blade (category.blade.php)
<div class="tree">
#include('category-list-widget',['categories' => $categories])
</div>
Blade (category-list-widget.blade.php)
<ul>
#foreach($categories as $category)
<li>
<a>{{$category->name}}</a>
#if(!empty($category->children) && $category->children->count())
#include('category-list-widget',['categories' => $category->children])
#endif
</li>
#endforeach
</ul>
I did not test the code, Just wrote it here directly in the texteditor. I hope you get the idea.
I want to create dynamice mega menu but i'm getting error when i'm making tables relationship. Please let me know how can i make relationship.
Table structure Below:-
1) categories
id integer
category varchar
2) subcategories
id integer
subcategory varchar
category_id integer
3) parentcategories
id integer
parentname varchar
subcategory_id integer
Models
Categories.php
protected $table = "categories";
public function sub(){
return $this->hasManyThrough(Subcategories::class,Parentcategories::class,'subcategory_id','category_id');
}
Subcategories.php
protected $table = "subcategories";
public function category()
{
return $this->belongsTo('App\Categories');
}
Parentcategories.php
protected $table = "parentcategories";
public function subcategory()
{
return $this->belongsTo('App\Subcategories');
}
PagesController.php
public function index(){
$categories = Categories::all();
return view('pages.home')->with('categories',$categories);
}
blade template
#foreach($categories as $category)
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
{{ $category->category }} <i class="fa fa-chevron-down"
aria-hidden="true"></i>
</a>
<ul class="mega-menu dropdown-menu">
#foreach($category->sub->take(20) as $subcategory)
<li class="col-sm-3">
<h5>{{$subcategory->subcategory}} <i class="fa fa-caret-right" aria-hidden="true"></i></h5>
<ul class="mega-list">
<li>parent categories comes here</li>
</ul>
</li>
#endforeach
</ul>
</li>
#endforeach
Thanks
As I can see your table are hierarchy is in simillar fashion, I guess this can be done with single table. Create a table named categories and follow the below table structure:
Now create a model Category.php: something like this:
<?php
class Category extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'categories';
public function parent() {
return $this->hasOne('category', 'id', 'parent_id');
}
public function children() {
return $this->hasMany('category', 'parent_id', 'id');
}
public static function tree() {
return static::with(implode('.', array_fill(0, 4, 'children')))->where('parent_id', '=', NULL)->get();
}
}
Now in your controller suppose HomeController.php write:
<?php
class HomeController extends BaseController {
protected $layout = "layouts.main";
public function showWelcome()
{
$items = Category::tree();
$this->layout->content = View::make('layouts.home.index')->withItems($items);
}
}
And in views suppose index.blade.php you can simply pass like this:
<ul>
#foreach($items as $item)
<li>{{ $item->title }}
#foreach($item['children'] as $child)
<li>{{ $child->title }}</li>
#endforeach
</li>
#endforeach
</ul>
This works for n-number for hierarchy, more efficient and a single table categories, hope this helps
I have two models called category and sub-category
Category.php
class Category extends Model
{
protected $table = 'category';
public $timestamps = false;
public function subCategory(){
return $this->hasMany('App\Subcategory', 'category_id');
}
}
Subcategory.php
class Subcategory extends Model
{
protected $table = 'subcategory';
public $timestamps = false;
public function subCategory() {
return $this->belongsTo('App\Category');
}
and I have foreign key column called category_id in my subcategory table in database
this is how I am trying to get all the subcategories for the selected category in my controller
$subcategory = Category::all();
and my blade view
<ul>
#foreach($categories as $categories)
<li class='has-sub'><a href='#'>{{ $categories->category_name }}</a>
<ul>
#foreach($subcategory->subCategory() as $sub)
<li><a href='#'>{{ $sub->subcategory_name }}</a></li>
#endforeach
</ul>
</li>
#endforeach
</ul>
I am able to get all the categories name for now but I can't get the name of sub-categories for the category..What I am missing here?
Your models are fine, i would modify the controller and view to the following:
In your controller
$categories = Category::with('subCategory')->get();
Now in this this case, your categories will be eager loaded with your subcategories. In your example, you make queries in a foreach loop, which is not efficient.
In your view
<ul>
#foreach($categories as $category)
<li class='has-sub'><a href='#'>{{ $category->category_name }}</a>
<ul>
#foreach($category->subCategory as $sub)
<li><a href='#'>{{ $sub->subcategory_name }}</a></li>
#endforeach
</ul>
</li>
#endforeach
</ul>
Notice the variable names, as #aldrin27 mentioned in the comment! ($categories -> $category)
More tweaks
You could use one model for categories and subcategories:
function subCategory() {
return $this->hasMany('App\Category', 'category_id');
}
So i have in my database a table with id, id_parent, title and so on..
I need to create a list with sublists from that. I need some sort of recursive function but don't know how to do that in laravel..
I tried
class Goals extends Model {
protected $table = 'goals';
public function subgoals() {
return $this->hasMany(SubGoals::class, 'id_category');
}
}
class SubGoals extends Model {
protected $table = 'goals';
public function goals() {
return $this->belongsTo(Goals::class, 'id_category');
}
}
Controller:
$treeView = Goals::with(['SubGoals'])->get();
And view:
#foreach($treeView as $category)
<li>
{{ $category->title }}
<ul>
#foreach($category->subgoals as $subcategory)
<li>{{ $subcategory->title }}</li>
#endforeach
</ul>
</li>
#endforeach
Didn't get the right result..
Maybe someone have a snippet..
You dont need to create 2 classes, just need one like your example Goal.
class Goal extends Model {
protected $table = 'goals';
public function subgoals() {
return $this->hasMany(Goal::class, 'parent_id', 'id');
}
}
then in the controller you need to "Query all parent Goals" like this:
$parent_goals = Goal::whereNull('parent_id')->get();
and finally in the view:
#foreach($parent_goals as $goal)
<li>
{{ $goal->title }}
<ul>
#foreach($goal->subgoals as $subgoal)
<li>{{ $subgoal->title }}</li>
#endforeach
</ul>
</li>
#endforeach
that's it. hope that help's you.