laravel - home route - php

I'm learning Laravel, and for my first project I'd like to create my portfolio. However, the first task I have to do is confusing me.
So I created my templates, layout.blade.php and home.blade.php. That makes sense to me, but now how do I tell Laravel, or how do I route to home.blade.php?
I'm looking for an explanation rather then just code. I'm trying to learn.

Actually, a view in MVC application is just a part of the application and it's only for presentation logic, the UI and one doesn't call/load a view directly without the help of another part (controller/function) of the application. Basically, you make a request to a route and that route passes the control over to a controller/function and from there you show/load the view. So it's not a tutorial site and it's also not possible to explain about MVC here, you should read about it and for Laravel, it's best place to understand the basics on it's documentation, well explained with examples, anyways.
In case of Laravel, you should create a controller/class or an anonymous function in your apps/routes.php file and show the view from one of those. Just follow the given instruction step by step.
Using a Class:
To create a route to your Home Controller you should add this code in your app/routes.php
// This will call "showWelcome" method in your "HomeController" class
Route::any('/', array( 'as' => 'home', 'uses' => 'HomeController#showWelcome' ));
Then create the HomeController controller/class (create a file in your controllers folder and save this file using HomeController.php as it's name) then paste the code given below
class HomeController extends BaseController {
public function showWelcome()
{
// whatever you do, do it here
// prepare some data to use in the view (optional)
$data['page_title'] = 'Home Page';
// finally load the view
return View::make('home', $data);
}
}
If you have {{ $title }} in your home.blade.php then it'll print Home Page. So, to use a view you need a controller or an anonymous function and load the view from the controller/function.
Using an anonymous function:
Also, you can use an anonymous function instead of a controller/class to show the view from directly your route, i.e.
Route::any('/', function(){
// return View::make('home');
// or this
$data['page_title'] = 'Home Page'; // (optional)
return View::make('home', $data);
});
Using this approach, whenever you make a request to the home page, Laravel will call the anonymous function given in/as route's callback and from there you show your view.
Make sure to extend the the master/main layout in sub view (home):
Also, remember that, you have following at the first line of your home.blade.php file
#extends('layouts.layout')
It looks confusing, you may rename the main layout (layout.blade.php) to master.blade.php and use following in your home.blade.php instead
#extends('layouts.master')
Read the doc/understand basics:
You should read Laravel's documentation properly, (check templates to understand blade templating) and also read some MVC examples, that may help you too understand the basics of an MVC framework (you may find more by googling) and some good posts about MVC on SO.

Check it routing in Laravel.
You need to use route file and controllers
Create needed function in your Controller file and create a template file for example
class UserController extends BaseController {
/**
* Show the profile for the given user.
*/
public function showProfile($id)
{
$user = User::find($id);
return View::make('user.profile', array('user' => $user));
}
}
you need to create view file views/user/profile.blade.php
View::make('user.profile', array('user' => $user)) == views/user/profile.blade.php
And you should read it http://laravel.com/docs/responses and also this http://laravel.com/docs/quick#creating-a-view

Related

How to make the controller data override view controller in Laravel?

To build a sidebar that has a lot of dynamic data on it I learned about View composers in Laravel. The problem was that View Composers trigger when the view loads, overriding any data from the controller for variables with the same name. According to the Laravel 5.4 documentation though, I achieve what I want with view creators :
View creators are very similar to view composers; however, they are
executed immediately after the view is instantiated instead of waiting
until the view is about to render. To register a view creator, use the
creator method:
From what I understand, this means if I load variables with the same name in the controller and the creator, controller should override it. However this isn't happening with my code. The view composer:
public function boot()
{
view()->creator('*', function ($view) {
$userCompanies = auth()->user()->company()->get();
$currentCompany = auth()->user()->getCurrentCompany();
$view->with(compact('userCompanies', 'currentCompany'));
});
}
And here is one of the controllers, for example:
public function name()
{
$currentCompany = (object) ['name' => 'creating', 'id' => '0', 'account_balance' => 'N/A'];
return view('companies.name', compact('currentCompany'));
}
the $currentCompany variable in question, for example, always retains the value from the creator rather than being overridden by the one from the controller. Any idea what is wrong here?
After some research, I realized my initial assumption that the data from the view creator can be overwritten by the data from the controller was wrong. The creator still loads after the controller somehow. But I found a simple solution.
For those who want to use View composers/creators for default data that can get overwritten, do an array merge between the controller and composer/creator data at the end of the boot() method of the composer/creator, like so:
$with = array_merge(compact('userCompanies', 'currentCompany', 'currentUser'), $view->getData());
$view->with($with);

PHP MVC understanding help (Laravel 5.3)

First, I want to say that it's the first time for me working
with a PHP Framework and MVC and I have not found all the answers to my problems yet. I'm using Laravel 5.3 at the moment.
Problem:
I have a website where a User can login and a few pages (I'm using Laravel Auth) and on a lot of pages I have a sidebar which is every time the same. Then I have on every page some content which is different (about, articles, ...). I heard that the most important thing is that you should never write code twice and there is the problem. On this sidebar there is a "service" which show content to the user but to show this I have an algorithm which needs the user data from the authenticated user and the Auth function is not available in Laravel 5.3 ServiceProvider or BaseController and was never meant to be.
My question now is how can I do that cleanly?
Some codes to understand it better:
Routes:
Route::get('/community/ranking', 'Pages\RankingController#getView');
Route::get('/community/advertising', 'Pages\AdvertisingController#getView');
Route::get('/logout', 'PagesController#doLogout');
Route::get('/home', 'Pages\HomeController#getView');
Then I have for every page an own controller which serves the content for this page (except of the sidebar - no solution yet).
HomeController:
<?php
namespace App\Http\Controllers\Pages;
use App\Http\Controllers\BaseController;
use Redis;
use App\Http\Requests;
use Request;
use Shoutbox;
use User;
class HomeController extends BaseController
{
function getView()
{
$shoutboxData = $this->getShoutboxData();
return view('pages.home', compact('shoutboxData'));
}
private function getShoutboxData()
{
$shoutbox = Shoutbox::orderBy('time', 'DESC')->skip(0)->take(15)->get();
if(count($shoutbox) > 0)
{
foreach($shoutbox as $entry)
{
$getUser = User::where('id', '=', $entry->user_id)->first();
$entry['username'] = $getUser->username;
$entry['look'] = $getUser->look;
$shoutboxData[] = $entry;
}
}
else
{
$shoutboxData = null;
}
return $shoutboxData;
}
public function systemMessage()
{
$redis = Redis::connection();
$redis->publish('chat.message', json_encode([
'msg' => 'System message',
'nickname' => 'System',
'system' => true,
]));
}
}
Now I serve the view in each, own controller and the content of this page (for example shoutbox, news) is also in that controller. (Not very clean in my opinion but didnt find any better way. Something I can improve here?).
I can serve the sidebar content on every Controller but this is not what I want. How can I do that? Am I using MVC right?
Thanks in advance!
Because you're using the Laravel Blade template system you can split your view logic out into separate blade files.
Your sidebar is common to every page so put this in your layout file (resources/views/layouts/app.blade.php) put the logic before
<div class="container" id="app">
#yield('content')
</div>
Now in your blade files for each individual page just extend the layout template you just created:
#extends('layouts.app')
#section('content')
<h1>page content goes here</h1>
#endsection
Now everyone of your blade files which extend the layouts.app will have the sidebar logic in them.
EDIT: With the extra information provided.... do as I said above but also create a view composer, you can find the full documentation here: https://laravel.com/docs/5.3/views#view-composers
Create a view composer for your main layout (or sidebar layout if you're going to be extending layouts instead) and pass your data within the view composer, the documentation gives good examples so just modify that for your own sidebar.

Laravel RESTful controller to include subdirectory for 'show' function

I am building my Laravel app through the use of RESTful controllers.
Currently, an 'agent' can login, to view all of their 'notifications'.
The structure is:
/agents
When they chose a notification to view, instead of:
/agents/$id
I want it to be:
/agents/notifications/$id
Solely because it follows logically. If it was '/agents/$id' I would expect to see the agent's profile, for example.
Is there a way of including a subdirectory into the 'show' function? Or do I need to create a notification controller that somehow sites within the agent directory.
My route is:
Route::controller('agents', 'AgentsController');
With the show function:
public function show($id)
{
$alerts = Alert::where('id', $id)->first();
$this->layout->content = View::make('agents.notification.show', array('alerts' => $alerts));
}
Any help would be hugely appreciated.
if you want to use http://laravel.com/docs/controllers#restful-controllers then your controller's method should be named getShow().
Apart from that you can achieve what you want by defining another route like this:
Route::get('agents/notifications/{id}', 'AgentsController#getShow');

Laravel : Using controller in included view

I have a view that is rendered with its controller. The function that calls the view is linked in my routes. It works fine when directly accessing the route, but obviously my controller is not included when I include it in my template.
How do I use my controller when I include my view?
I'm on Laravel 3.
Right now I have my controller :
public function get_current()
{
// $sales = ...
return View::make('sale.current')->with('sales',$sales);
}
My route (which obv only work on GET /current) :
Route::get('current', 'sale#current');
My master view
#include('sale.current')
Then my sale.current view calls $sales
#foreach($sales as $sale)
Thanks!
So this is the case when you want to call some laravel controller action from view to render another partial view. Although you can find one or another hack around it. However, please note that laravel controllers are not meant for that.
When you encounter this scenario when you want to reuse the same view again but don't want to supply all necessary data again & again in multiple controller actions, it's the time you should explore the Laravel View Composers.
Here is the official documentation link : https://laravel.com/docs/master/views#view-composers
Here is the more detailed version of it :
https://scotch.io/tutorials/sharing-data-between-views-using-laravel-view-composers
This is the standard way of achieving it without any patch work.
Your question is still unclear but I can try to help you. I did a small example with the requirements you gave. I create a route to an action controller as follows:
Route::get('test', 'TestController#test');
In TestController I define the action test as follows:
public function test()
{
return View::make('test.home')->with('data', array('hello', 'world', '!'));
}
According to your asking, you defined a view who includes content from another view (layout) and in that layout you use the data passed for the action controller. I create the views as follows:
// home.blade.php
<h1>Message</h1>
#include('test.test')
and
// test.blade.php
<?php print_r($data); ?>
When I access to "test" I can see print_r output. I don't know if that is what you are doing, but in my case works fine.
I hope that can help you.

Laravel: Passing default variables to view

In Laravel, we all pass data to our view in pretty much the same way
$data = array(
'thundercats' => 'Hoooooooooooh!'
);
return View::make('myawesomeview', $data);
But is there some way to add default variables to the view without having to declare it over and over in $data? This would be very helpful for repeating variables such as usernames, PHP logic, and even CSS styles if the site demands it.
Use View Composers
View composers are callbacks or class methods that are called when a
view is created. If you have data that you want bound to a given view
each time that view is created throughout your application, a view
composer can organize that code into a single location. Therefore,
view composers may function like "view models" or "presenters".
Defining A View Composer :
View::composer('profile', function($view)
{
$view->with('count', User::count());
});
Now each time the profile view is created, the count data will be bound to the view. In your case, it could be for id :
View::composer('myawesomeview', function($view)
{
$view->with('id', 'someId');
});
So the $id will be available to your myawesomeview view each time you create the view using :
View::make('myawesomeview', $data);
You may also attach a view composer to multiple views at once:
View::composer(array('profile','dashboard'), function($view)
{
$view->with('count', User::count());
});
If you would rather use a class based composer, which will provide the benefits of being resolved through the application IoC Container, you may do so:
View::composer('profile', 'ProfileComposer');
A view composer class should be defined like so:
class ProfileComposer {
public function compose($view)
{
$view->with('count', User::count());
}
}
Documentation and you can read this article too.
There are couple of ways, so far I have been experiment with some.
1.Use singleton, you can put it in routes.php
App::singleton('blog_tags', function() {
return array(
'Drupal' => 'success',
'Laravel' => 'danger',
'Symfony' => 'dark',
'Wordpress' => 'info'
);
});
2.Use Settings bundle, download here. https://github.com/Phil-F/Setting. You can put this in controller or template.
Setting::set('title', 'Scheduler | Mathnasium');
3.Use View share, pretty much use it in your template
Controller: Views::share('theme_path', 'views/admin/');
Template: <link href="{{ $theme_path }}/assets/bootstrap.min.css"/>
4.My current sample setup, I wrote a construct in HomeController.
public function __construct()
{
// Define a theme namespace folder under public
View::addLocation('../public/views/admin');
View::addNamespace('admin', '../public/views/admin');
View::share('theme_path', 'views/admin/');
// Set default page title
Setting::set('title', 'Scheduler | Mathnasium');
Setting::set('description', 'daily customer scheduler.');
Setting::set('keywords', ['Reservation', 'Planner']);
Setting::set('page-title', '');
}
#enchance, as an alternative to using '*', as mentioned in your comment, perhaps a View::share would help you too. From the Laravel documentation:
You may also share a piece of data across all views:
View::share('name', 'Steve');
Excerpt is from http://laravel.com/docs/responses
Yep there absolutely is a way - see here on view composers.
You can use that to add data to a view or set of views.

Categories