Dyanmic url in laravel - php

I am a beginner in laravel so please excuse me if this is a simple question
I am trying to pass a db variable through my url so e.g blog?=category
It displays all results but when i change the url to blog/category1 it doesn't display anything.
DB Fields:id,category, name
1 category1 test
This is in my routes:
Route::get( '/blog', 'BlogController#index' );
Route::get('/', 'HomeController#index');
Route::get('blog/{category}', function($category = null)
{
// get all the blog stuff from database
// if a category was passed, use that
// if no category, get all posts
if ($category)
$posts = Post::where('category', '=', $category);
else
$posts = Post::all();
// show the view with blog posts (app/views/blog.blade.php)
return View::make('blog.index')
->with('posts', $posts);
});
BlogController
class BlogController extends BaseController {
public function index()
{
// get the posts from the database by asking the Active Record for "all"
$posts = Post::all();
// and create a view which we return - note dot syntax to go into folder
return View::make('blog.index', array('posts' => $posts));
}
}
This is my view layout:
#extends('base')
#section('content')
#foreach ($posts as $post)
<h2>{{ $post->id }}</h2>
<p>{{ $post->name }}</p>
#endforeach
#stop
Thanks

You need to add ->get() after your Eloquent query to fetch the results.
Route::get('blog/{category}', function($category = null)
{
// get all the blog stuff from database
// if a category was passed, use that
// if no category, get all posts
if ($category)
$posts = Post::where('category', '=', $category)->get();
else
$posts = Post::all();
// show the view with blog posts (app/views/blog.blade.php)
return View::make('blog.index')->with('posts', $posts);
});

Related

How to Display All Categories in Laravel

Am trying to display all the category in the database on single post blade, however, am also display five out the category in the database as my navigation menu. I am not sure maybe its the loop I am using as I keep getting five categories instead of all categories.
public function index()
{
return view('index')->with('title', Setting::first()->site_name)
->with('categories', Category::take(5)->get())
->with('first_post', Post::orderBy('created_at', 'desc')->first())
->with('second_post', Post::orderBy('created_at', 'desc')->skip(1)->take(1)->get()->first())
->with('third_post', Post::orderBy('created_at', 'desc')->skip(2)->take(1)->get()->first())
->with('wordpress', Category::find(4))
->with('laravel', Category::find(3))
->with('settings', Setting::first());
}
Here is the code for my single post controller
public function singlePost($slug)
{
$post = Post::where('slug', $slug)->first();
$next_id = Post::where('id', '>', $post->id)->min('id');
$prev_id = Post::where('id', '<', $post->id)->max('id');
return view('single')->with('post', $post)
->with('title', $post->title)
->with('settings', Setting::first())
->with('categories', Category::all())
->with('next', Post::find($next_id))
->with('prev', Post::find($prev_id))
->with('tags', Tag::all())
->with('first_post', Post::orderBy('created_at', 'desc')->first())
->with('second_post', Post::orderBy('created_at', 'desc')->skip(1)->take(1)->get()->first())
->with('third_post', Post::orderBy('created_at', 'desc')->skip(2)->take(1)->get()->first());
}
This is how I passed the value in the single.blade.php
#foreach($categories as $category)
<div class="post-category-wrap">
<div class="category-post-item">
<!-- <span class="post-count">168</span> -->
<a href="{‌{route('category.single', ['id' => $category->slug])}}" class="category-title">{‌{$category->name}}
<i class="seoicon-right-arrow"></i>
</a>
</div>
</div>
#endforeach
I think you should change the var name in index query for 'categories'. Something like
->with('categories_to_navigation', Category::take(5)->get()).
If the view single.blade.php extend index.blade.php this var names are being overwritten.

Recent post not displaying correctly

Here's the controller file code:
public function viewpost($url)
{
$url ='articles/'.$url;
if(count(posts::where('url', '=', $url)->first())<>1) {
return redirect()->back();
}
$posts = posts::all();
return view('viewpost')->with([
'posts' => posts::all(),
'post' => posts::where('url', '=', $url)->first()
]);
}
The normal URL of a post is supposed to be website.com/articles/name-of-post-here. In the sidebar, the posts are now being displayed as website.com/articles/articles/name-of-post-here
Example of a live post:
https://collegeconnect.ph/articles/how-to-improve-your-study-habits
Also, some of the posts have the status of "trashed" in the database. How can I only display posts with the stats of "active"?
My view code:
#foreach($posts as $post)
<p><img style="width:100px;" src="{{asset('thumbnails/'.$post->thumbnail)}}" class="responsive"><br>
{{substr(($post->title),0,88)}}..</p>
</tr>
#endforeach
Your making 4 database calls in your example, Better to just get the data once from the DB and work with the data.
Also I would be getting post id, Allot cleaner. But if you want name you can change id to name.
in routes/web.php
Route::get('/articles/{url}', 'Auth\HomeController#viewpost');
in Controller
public function viewpost($url){
$url = 'articles/'.$url;
$posts = posts::where('post_status', '')->get();
$post = $posts->where('url', $url)->first()
if ( empty($post) )
return redirect()->back();
return view('viewpost')->with('post', $post)->with('posts', $posts);
Then in view $post will be available eg
<h1>{{ $post->title }}</h1>
Then in the foreach $posts loop in the view change it to
<img style="width:100px;" src="{{asset('thumbnails/'.$post->thumbnail)}}" class="responsive">

having laravel category (slug based) posts with pagination

I have this function, where i get my categories base on their slug
public function postcategoryposts($slug){
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
return view('front.postcategory-posts', compact('category'));
}
Currently i'm getting my each category posts in blade like:
#foreach($category->posts as $post)
{{$post->title}}
#endforeach
until here everything is normal, the problem is how to divide my posts into pages? I am not able to use:
$category = PostCategory::where('slug','=',$slug)->paginate(10);
because I'm using
firstOrFail();
any idea?
You need to add a function to your model to get posts and then paginate.
In your controller
public function postcategoryposts($slug)
{
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
$posts = $category->getPaginatedPosts(10);
return view('front.postcategory-posts', compact('posts'));
}
In your model
// PostCategory model
public function getPaginatedPosts($limit = 10)
{
// Get category posts using laravel pagination method
return Post::where('category_id', '=', $this->id)->paginate($limit);
}
In your blade view
<div class="container">
#foreach ($posts as $post)
{{ $post->title }}
#endforeach
</div>
{{ $posts->render() }}
More informations about Laravel pagination here
Hope it's helps you :)

Defining multiple variable laravel for use in if statement

I would like to be able to display different content depending on which variable is called in the url.Ignoring the fact $slug is slug, let's say it's a post id instead so if $id is active then show just the post else if $month is active show all posts from that month elseif $month and $id = null show all. That's what I'm trying to achive
Routes.php
Route::get('blog/{slug}', ['as' => 'blog.slug', 'uses' => 'BlogController#getSlug']);
Route::get('blog/{month}', ['as' => 'blog.slug', 'uses' => 'BlogController#getSlug']);
BlogController.php
<?php
class BlogController extends BaseController {
public function BlogIndex()
{
//get the posts from the database by asking the Active Record for "all"
$blogs = Blog::all();
$blogs = DB::table('blogs')->paginate(3);
// and create a view which we return - note dot syntax to go into folder
return View::make('pages.blog', array('blogs' => $blogs));
}
public function ShowbySlug($slug)
{
$blogs = Blog::where('slug', '=', $slug)->get();
// show the view with blog posts (app/views/pages/blog.blade.php)
return View::make('pages.blog')
->with('slug', $slug)
->with('blogs', $blogs);
}
public function ShowbyMonth($month)
{
$blogs = Blog::where('month', '=', $month)->get();
// show the view with blog posts (app/views/pages/blog.blade.php)
return View::make('pages.blog')
->with('month', $month)
->with('blogs', $blogs);
}
}
blog.blade.php
#foreach ($blogs as $blog)
#if(isset($blogs))
<div class="blog-outer-wrap">
<img src="images/blog/{{ $blog->img}}">
<div class="blog-header">{{ $blog->header }}</div>
<div class="blog-text">{{ $blog->content }}</div>
<a href="{{ URL::route('blog.slug', [$blog->slug]) }}">
</div>
#elseif(isset($slug))
<div class="blog-outer-wrap">
<img src="images/blog/{{ $blog->img}}">
<div class="blog-header">{{ $blog->header }}</div>
<div class="blog-text">{{ $blog->content }}</div>
</div>
#endif
#endforeach
You really can't do that, because you just declared the same route twice. When you say a route is blog/{slug}, slug is only a placeholder. It's exactly the same¹ as blog/{month}. All it says is: "I expect blog/ followed by anything." It doesn't matter if you call your anything slug or month. That is, the parameters do not add up.
What you can do is, if you consider slug is always a string and month is always a number (or the name of the month²), is to apply where clauses to your route parameters, like so:
// Route for all blog posts
Route::get('blog', 'BlogController#showAll');
// Route for all blog posts in a month; only numbers as parameters
Route::get('blog/{month}', 'BlogController#showByMonth')
->where('month', '[0-9]+');
// Route for all blog posts by title; anything else as parameters
Route::get('blog/{slang}', 'BlogController#showBySlang');
And on your controller, define three methods, one for each route:
public function showAll() {
$blogs = Blog::all();
return View::make('pages.blog')
->with('blogs', $blogs);
}
public function showByMonth($month) {
$blogs = Blog::where('month', $month)
->get();
return View::make('pages.blog')
->with('blogs', $blogs);
}
public function showBySlug($slug) {
$blogs = Blog::where('slug', $slug)
->get();
return View::make('pages.blog')
->with('blogs', $blogs);
}
¹ Unless you're using some more advanced routing features, but that's not really the point here.
² It is doable with the where clause, but it would be ugly if you wanted to consider all upper/lower case combinations. E.g: ([Jj][Aa][Nn][Uu][Aa][Rr][Yy]|[Ff][Ee][Bb][Rr][Uu][Aa][Rr][Yy]|...)

How to store homepage in cache in laravel 4

I am new in laravel and php. I am developing a magazine site with laravel 4. I want to store home page in laravel cache . But In my homepage , there are many queries . Please see details below.:
My HomepageController index method:
public function index()
{
return View::make('homepage');
}
My Query Helper Function which is used for post by category in my Homepage:
public static function cat_post($category, $limit)
{
$posts = Post::whereHas('categories', function($q) use ($category)
{
$q->where('category_slug', 'like', $category);
})->with('categories')->take($limit)->orderBy('created_at', 'DESC')->get();
return $posts;
}
In My homepage.blade.php , I used this helper function many times. like below:
<?php $national = Helper::cat_post('national', 3); ?>
#foreach ($national as $post)
{{ Helper::img_src($post) }}
<h4>{{ $post->title }}</h4>
</div>
#endforeach
Now i want to put homepage in cache and when new post created, then delete old homepage from cache and store new one.
Please help me. Is it possible ?????
To store a value in cache you can use Laravel's Cache:
public function index()
{
return Cache::rememberForever('homepageCache', function()
{
return View::make('homepage');
});
}
This snipped tries to retrieve a cached version of View::make('homepage') and otherwise creates it.
Every time a post is created, updated or deleted you need to invalide your homepageCache:
Cache::forget('homepageCache');

Categories