Laravel 4 specific view not loading - laravel

I am new to laravel and following a tutorial for a basic app. So far the app has a default view layouts/default.blade.php, a partial _partials/errors.blade.php and three other views questions/index.blade.php, users/new.blade.php and users/login.blade.php
The routes are defined like so
// home get route
Route::get('/', array('as'=>'home', 'uses'=>'QuestionsController#get_index'));
//user register get route
Route::get('register', array('as'=>'register', 'uses'=>'usersController#get_new'));
// user login get route
Route::get('login', array('as'=>'login', 'uses'=>'usersController#get_login'));
//user register post route
Route::post('register', array('before'=>'csrf', 'uses'=>'usersController#post_create'));
// user login post route
Route::post('login', array('before'=>'csrf', 'uses'=>'usersController#post_login'));
questions/index.blade.php and users/new.blade.php load fine and within default.blade.php
when I call /login a blank page is loaded not even with default.blade.php. I am guessing that there is a problem in my blade syntax in login.blade.php given the fact that the default.blade.php works on the other routes and as far as I can see everything else is the same but if that was teh case wouldnt the default.blade.php route at least load?
the controller method this route is calling is as follows
<?php
Class UsersController extends BaseController {
public $restful = 'true';
protected $layout = 'layouts.default';
public function get_login()
{
return View::make('users.login')
->with('title', 'Make It Snappy Q&A - Login');
}
public function post_login()
{
$user = array(
'username'=>Input::get('username'),
'password'=>Input::get('password')
);
if (Auth::attempt($user)) {
return Redirect::Route('home')->with('message', 'You are logged in!');
} else {
return Redirect::Route('login')
->with('message', 'Your username/password combination was incorrect')
->withInput();
}
}
}
?>
finally login.blade.php
#section('content')
<h1>Login</h1>
#include('_partials.errors')
{{ Form::open(array('route' => 'register', 'method' => 'POST')) }}
{{ Form::token() }}
<p>
{{ Form::label('username', 'Username') }}
{{ Form::text('username', Input::old('username')) }}
</p>
<p>
{{ Form::label('password', 'Password') }}
{{ Form::text('password') }}
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close()}}
#stop

You could also define the layout template directly from the Controller , this approach provides more flexibility , as the same View can be used with multiple layout templates .
<?php namespace App\Controllers ;
use View , BaseController ;
class RegisterController extends BaseController {
protected $layout = 'layouts.master';
public function getIndex()
{
// Do your stuff here
// --------- -------
// Now call the view
$this->layout->content = View::make('registration-form');
}
}
My example uses Namespaced Controller but the same concepts are applicable on non-Namespaced Controllers .
Notice : Our RegisterController extends Laravel's default BaseController , which makes a bit of preparation for us , see code below :
<?php
class BaseController extends Controller {
/**
* Setup the layout used by the controller.
*
* #return void
*/
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
}
}
}
If a custom "Basecontroller" is defined , make sure that it also implements the "preparation" code .

I don't know what concepts are new to you , so let me make a couple arbitrary assumptions . If "namespace" and "Basecontroller" are << strange words >> , let me try to demystify these words .
Namespace : PHP's documentation is pretty well documented on this subject . My oversimplified explanation is as follows : Two skilled developers (JohnD and Irish1) decide to build their own PHP Logging Library and release the code as open source to the community .Most likely they will name their library "Log"
Now another developer would like to implement both libraries into his/her project (because JohnD's code uses MongoDB as storage medium while Irish1's code uses Redis ) . How would PHP's interpreter distinguishes the two code-bases from each other ? Simply prepend each library with a vendor name (JhonD/Log and Irish1/Log ) .
Basecontroller : Most likely your Controllers will share common functionality (a database connection , common before/after filters , a common template for a View ...... ) . It is a good practice not to define this "common functionality" into each Controller separately, but define a "Parent" Controller , from which all other Controllers will inherit its functionality . So later on , if you decide to make changes on the code , only one place should be edited .
My previous example uses " class RegisterController extends BaseController " , that BaseController is just checking if our (or any other) Child-controller has defined a property with the name of " $layout " , and if so , the View that it will instantiate will be encapsulated into that specified layout . See Laravel's flexibility , a group of Controllers share common functionality (by extending Basecontroller) but also are free to choose their own layout (if they desire to do so ) .

I have found my error
I did not have #extends('layouts.default') at the beginning of the login.blade.php template

Related

Laravel eager model loading with custom attribute

Is there any possible way to get a custom attribute value through eager load
For instance, given this custom attribute on a model:
class User extends Model {
protected $appends = ['is_member'];
public function getIsMemberAttribute() {
return 'yes';
}
}
and related model
class Awards extends Model {
public function owner(){
return $this->belongsTo('App\User');
}
}
I would love to be able to get is_member attribute in collection using request below:
$users=Awards::orderBy('created_at')->with('owner')->get();
According to Laravel's documentations, $appends is used for appending in array and JSON only...
Once the attribute has been added to the appends list, it will be included in both the model's array and JSON forms.
So, when you do something like dd($user). You will not be able to see the is_member field, but when you do something like $user->toArray() or $user->toJson() you will.
Basically, for places wherever is_member field is always present. All you need to do to access it is (say in Page View/Blade etc)
public function show($id) {
$user = User::get($id);
return view('users.show', ['user' => $user->toArray()]);
}
And then do,
Is Member? : {{ $user['is_member'] }}
// Or if you don't like blade you can do this
// Is Member? : <?php echo $user['is_member'] ?>
But as written in the comments by #Amit, there is no use case of this until you are using it for the sole purpose of APIs. For blade etc, you should prefer doing this
Is Member? : {{ $user->is_member ? 'Yes' : 'No' }}
// Again if you don't like blade you can do this
// Is Member? : <?php echo $user['is_member'] ? 'Yes' : 'No'; ?>
Hope this clears your doubts :)

Laravel passing data to page

I am trying to pass data to Controller of Laravel. here is how I do that :
in PagesController::
class PagesController extends Controller
{
public function contact(){
$data="some random ";
return view('contact',compact("data"));
}
}
now in contact.blade.php :
contact pages {{ $data }}
and it s hows
Whoops, looks like something went wrong.
What may be a problam?
try this
public function contact()
{
$data = 'some random';
return View('contact')->with('data' , $data );
}
make sure that the view works fine (if its inside a folder use return View('foldername.contact')
make sure that your view name is contact.blade.php (check uppercase letters)
and inside your view
this is my {{ $data }}

Store method not working using resource route

I am having trouble figuring out why my data is not being posted and stored in my database. I have used the resource routes for another form and it works fine, but here for some reason it won't work. Clicking submit just seems to refresh the page, no errors to work from!
So I have a form which gets the workout routines from a database, and on submission I want this to create a new Workout "session" in my database table (called "Workouts"). The form is this:
{{ Form::open(array('url' => '/')) }}
<div class="form-group">
{{ Form::text('workout_name', Input::old('workout_name'), array('class' => 'form-control', 'placeholder' => 'Session Name')) }}
</div>
<div class="form-group">
{{ Form::select('routines', $routine_names, null, array('class' => 'form-control')) }}
</div>
{{ Form::submit('Select Routine', array('class' => 'btn btn-success pull-right')) }}
{{ Form::close() }}
In my HomeController I have this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Routine;
use App\Workout;
class HomeController extends Controller
{
public function index()
{
$routines = Routine::all();
$routine_names = Routine::lists('routine_name');
return view('workout')->with(array('routines'=>$routines, 'routine_names'=>$routine_names));
}
public function store()
{
$workout = new Workout;
$workout->workout_name = Input::get('workout_name');
$workout->save();
}
}
I have a model created for the Workout, and the route for this page is the following:
Route::resource('/', 'HomeController');
I can't figure out where I'm going wrong. The index method in my controller is working, as it is returning the correct view with the data I need. The form also looks OK I think, as I'm posting to the same page, but submitting doesn't seem to carry out the code I have in the store method of the HomeController.
Any help would be appreciated!
Thanks :)
Change your route declaration from:
Route::resource('/', 'HomeController');
To something like this:
Route::resource('/workout', 'WorkoutController');
If you are using the resources controller creator command of php artisan then all the specific routes are created for you. To see all listed routes you can type , php artisan routes. This will show you RESTFUL routes even for your POST method .
And also even you did not created the resources controller and did made the routes with manual way then you can create ,
Route::POST('/workout' , SomeController#post);
I am trying to say , you have to use the different POST method for the form submission .
Hope this will solve your problem . Thanks.

How to implement a generic view presenter in Laravel

I am currently using laracasts/Presenter to handle logic related to my views, this implementation is connected to a model. But I also have some generic view logic that I would like to implement, what is the best practice for creating this?
I have tried two methods, but neither feels right:
Custom class ViewHelper with static functions, called with ViewHelper::Method.
Blade include files, called with #include('includes.navicon')
Is there a better way of doing this? Or is one (or both) of the above acceptable?
Edit: We're talking simple stuff here like insert page title, run text though Markdown parser. This is an example of a function that I use on all pages, it just creates and returns a page header.
public static function PageTitle($level, $title, $small = null)
{
if ($small != null) $title = $title . " <small>" . $small . "</small>";
$html = "<div class=\"page-header\" style=\"margin-top: 0px\"><h%1\$d>%2\$s</h%1\$d></div>";
return sprintf($html, $level, $title);
}
The view presenter that I have installed makes use of the model, so to get a formatted URL for example I would use the command: {{ $article->present()->url }}, while this generic view logic should be available in all views without having to add it to all the models.
I ended up creating a base class that all view presenters extend, and move everything generic there. Functions that is required on views that do not have a model I simply added as static.
Model, I added $presenterInfo to pass information to load the correct view(s) and use as a title prefix. The rest is required by the view presenter.
use Laracasts\Presenter\PresentableTrait;
...
use PresentableTrait;
protected $presenter = 'ArticlePresenter';
public $presenterInfo = ['view' =>'articles', 'category' => 'Article'];
Baseclass, everything generic goes here. So basically everything that might be useful on multiple classes and their views.
use Laracasts\Presenter\Presenter;
class BasePresenter extends Presenter {
public static function pageHeader($level, $title, $small = null)
{
if ($small != null) $title .= " <small>" . $small . "</small>";
$html = "<div class=\"page-header\" style=\"margin-top: 0px\"><h%1\$d>$this->presenterInfo['category']: %2\$s</h%1\$d></div>";
return sprintf($html, $level, $title);
}
public function url()
{
return URL::route($this->presenterInfo['view'] . '.show', array('id' => $this->id, 'slug' => Str::slug($this->title)));
}
}
Viewclass, functions that will only be available for the selected class; in this case Article.
class ArticlePresenter extends BasePresenter {
// Example function only needed by the article class.
public function stump()
{
return Str::limit($this->content, 500);
}
}
Examples, loading view presenter data:
// Show page header level 2
{{ BasePresenter::pageHeader(2, 'Articles') }}
// Enumerate the articles and show title, stump and read more link
#foreach($articles as $article)
<article>
<h3>{{ HTML::link($article->present()->url, $article->title) }}</h3>
<div class="body">
<p>{{ $article->present()->stump }}</p>
<p>Read more...
</div>
</article>
#endforeach

Laravel 4 MethodNotAllowedhttpException

I am get a MethodNotAllowedHttpException when I submit the form detailed below. The route appears correct to me and is syntactically the same as other post routes that are working just fine. The controller method exists but even so I think the exception is occuring before the request gets to the controller as item 4 on the left of the laravel error page says handleRoutingException right after item 3 which says findRoute. I am pretty sure I am not using restful routing the way you should in laravel 4 but that is because the tutorial I am following a laravel 3 tutorial and updating hte syntax to 4 as I go but like I said the other routes work fine so I can't figure out why this one isn't.
Template
#extends('layouts.default')
#section('content')
<div id="ask">
<h1>Ask a Question</h1>
#if(Auth::check())
#include('_partials.errors')
{{ Form::open(array('ask', 'POST')) }}
{{ Form::token() }}
<p>
{{ Form::label('question', 'Question') }}
{{ Form::text('question', Input::old('question')) }}
{{ Form::submit('Ask a Question') }}
</p>
{{ Form::close() }}
#else
<p>
<p>Please login to ask or answer questions.</p>
</p>
#endif
</div><!-- end ask -->
#stop
Route
Route::post('ask', array('before'=>'csrf', 'uses'=>'QuestionsController#post_create'));
Controller
<?php
class QuestionsController extends BaseController {
public $restful = true;
protected $layout = 'layouts.default';
public function __construct()
{
$this->beforeFilter('auth', array('post_create'));
}
public function get_index() {
return View::make('questions.index')
->with('title', 'Make It Snappy Q&A - Home');
}
public function post_create()
{
$validation = Question::validate(Input::all());
if($validation->passes()) {
Question::create(array(
'question'=>Input::get('question'),
'user_id'=>Auth::user()->id
));
return Redirect::Route('home')
->with('message', 'Your question has been posted.');
} else {
return Redirect::Route('register')->withErrors($validation)->withInput();
}
}
}
?>
I believe defining public $restful = true; is how it was done in Laravel 3. In Laravel 4 you define a restful controller in your routes like so:
Route::controller('ask', 'QuestionsController');
Then to define the functions you would not use an underscore to separate them. You must use camel case like so:
public function getIndex()
{
// go buck wild...
}
public function postCreate()
{
// do what you do...
}
For RESTful Controllers you should define the route using Route::controller method, i.e.
Route::controller('ask', 'QuestionsController');
and controller methods should be prefixed with http verb that it responbds to, for example, you may use postCreate and you have post_create instead, so it doesn't look like a Restful controller.
You are using public $restful = true; in your controller, this is not being used in Laravel-4, and public $restful = true; may causing the problem, so remove this line.

Resources