I am more efficient at setting up my view logic with straight up php. Blade is cool but it's not for me. I am trying to translate all the Blade specific examples and docs to just php. I don't like the fact that I need to assign all the variables for my views in an array of View::make(). I did found all of this so far.
controllers/home.php:
class Home_Controller extends Base_Controller {
public $layout = 'layouts.default';
public function action_index()
{
$this->layout->name = 'James';
$this->layout->nest('content', 'home.index');
}
}
views/layouts/default.php:
// head code
<?php echo Section::yield('content') ?>
// footer code
views/home/index.php
<?php Section::start('content'); ?>
<?php echo $name ?>
<?php Section::stop(); ?>
I am greeted with this error: Error rendering view: [home.index] Undefined variable: name. I know that $this->layout->nest('content', 'home.index', array('name' => 'James')); works but that negates my point about having to send all my variables to an array. This can't be the only way.
The view templating docs doesn't seem to touch on doing variables with nested views from controllers.
you can pass variables this way;
class Home_Controller extends Base_Controller {
public $layout = 'layouts.default';
public function action_index()
{
$this->layout->nest('content', 'home.index')
->with('name', 'James');
}
}
Here's an example of how I'm templating with laravel.
Class Products_Controller extends Whatever_Controller {
public $layout = 'layouts.main';
public function get_index()
{
// .. snip ..
$view = View::make('home.product')
->with('product', $product); // passing all of my variable to the view
$this->layout->page_title = $cat_title . $product->title;
$this->layout->meta_desc = $product->description;
$this->layout->content = $view->render(); // notice the render()
}
}
my main layout looks like
<html>
<head>
<title> {{ $page_title }} </title>
<meta name="description" content="{{ $meta_desc }}" />
</head>
<body>
{{ $content }}
</body>
</html>
and the home/product page looks like
<div class="whatev">
<h1> {{ $product->title }} </h1>
<p> {{ $product->description }} </p>
</div>
Hope that helps you clear some things up
I know it has been a while on this question, but since it was asked, Laravel 4 has come out and there are newer ways to do things.
If you are reading this these days you should consider using View Composers to prepare the data for your views.
Example:
class MyViewComposer {
public function compose($view){
$view->title = 'this is my title';
$view->name = 'joe';
...
$view->propertyX = ...;
}
}
After setting up your view composer register it with the app:
View::composer('home.index', 'MyViewComposer');
For more information check out the laravel docs on view composers:
http://laravel.com/docs/responses
Related
I am currently making an ecommerce site and am new to Laravel, and at the moment I'd like to retrieve data based on different categories from the same table, using a where clause to store the retrieved data in separate variables. The problem here is whenever I run this code it say undefined variable $newproducts. Below is my code. Thanks in advance
My Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\product;
class ProductsController extends Controller
{
public function index(){
$allproducts=product::all();
$bestsellerproducts=product::where('category','iphone 11')->get();
$newproducts=product::where('category','iphone 12')->get();
return view('test',['products'=>$allproducts],['bestsellerproducts'=>$bestsellerproducts],['newproducts'=>$newproducts]);
}
}
My view Template
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<h2>Best Seller products</h2>
#foreach($bestsellerproducts as $bestsellerproduct)
<label>Name</label>
{{ $bestsellerproduct['name'] }}
<label>Price</label>
{{ $bestsellerproduct['price'] }}
#endforeach<br>
<h2>New products</h2>
#foreach($newproducts as $newproduct)
<label>BaseName</label>
{{ $newproduct['name'] }}
<label>Price</label>
{{ $newproduct['price'] }}
#endforeach<br>
<h2>All products</h2>
#foreach($products as $product)
<label>BaseName</label>
{{ $product['name'] }}
<label>Price</label>
{{ $product['price'] }}
#endforeach<br>
</body>
</html>
You need to pass all view variables in a single array, not multiple arrays:
class ProductsController extends Controller
{
public function index(){
$allproducts=product::all();
$bestsellerproducts=product::where('category','iphone 11')->get();
$newproducts=product::where('category','iphone 12')->get();
return view('test',['products'=>$allproducts, 'bestsellerproducts'=>$bestsellerproducts,'newproducts'=>$newproducts]);
}
}
Alternatively you can use with:
class ProductsController extends Controller
{
public function index(){
$allproducts=product::all();
$bestsellerproducts=product::where('category','iphone 11')->get();
$newproducts=product::where('category','iphone 12')->get();
return view('test')
->with('products',$allproducts)
->with('bestsellerproducts', $bestsellerproducts)
->with('newproducts', $newproducts);
}
}
I'm a new to CodeIgniter and I have a problem when I display a list of items, I want each items to be a link, so when the user clicks that particular item, it will show the details of that item. Or perhaps give some suggestion on what I should google for. I have literally no idea whats terms or keywords that should I search about.
controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Site extends CI_Controller
{
public function index()
{
$this->getListOfAgent();
}
function getListOfAgent()
{
$this->load->model("agentDB_model");
$data['results'] = $this->agentDB_model->getAllAgentInfo();
$this->load->view("viewAgent_view", $data);
}
function userInformation()
{
//how to i get the selected item which the user clicked and show the details accordingly?
}
}
model
<?php
class agentDB_model extends CI_Model
{
function getAllAgentInfo()
{
$query = $this->db->query("SELECT * FROM user");
return $query->result();
}
function addAgent($newAgent)
{
$this->db->insert("user", $newAgent);
}
}
view
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome</title>
</head>
<body>
<div id="content">
<h1>Home Page</h1>
<p>List Of Agent in database</p>
</div>
<?php
foreach($results as $row)
{
echo "<a href = 'Site/userInformation'>$row->userName</a>";
echo "</br>";
echo "</br>";
}
//$this->load->controller(Site/userInformation);
?>
<div id="footer">
<p>Copyright (c) 2012 basicsite.com</p>
</div>
</body>
</html>
You need to tell the Site/userInformation method for what record you want the information. You use URI segments for this.
So, in your view, change the following line:
echo "<a href = 'Site/userInformation'>$row->userName</a>";
to:
echo "<a href = 'Site/userInformation/$row->userID'>$row->userName</a>";
Then, in your controller method, add the parameter to the method declaration:
function userInformation($userID)
{
// now, you use the model to get the correct record from the db based on
// the $userID and display the information
}
I am trying to get data out of my table, and send that array of output over to my view and there echo out specific parts of it.
I get an exception error: Undefined index bassengId.
index.php
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bassengweb</title>
</head>
<body>
<?php
if(isset($htt))
{
echo $htt['malingsId'];
}
?>
</body>
</html>
routes.php
Route::get('/', 'HomeController#showIndex');
Route::post('/data', 'HomeController#showInput');
homecontroller.php
public function showIndex()
{
return View::make('index');
}
public function showInput()
{
$htt = hvertredjetime::all();
return View::make('index')->with('htt', $htt);
}
If I try to just echo the $htt variable from index, I get:
[{"malingsId":1,"dato":"25.02.2014","tid":"12:44:00","frittKlor":"4.00","bundetKlor":"5.00","totalKlor":"9.00","ph":"7.00","autoPh":"8.00","autoKlor":"9.00","redox":"5.00","bassengId":1}]
I am a little stuck here, being new to this and not really seeing what I do wrong.
By using the ::all() method you are returning an array
public function showInput()
{
$htt = hvertredjetime::all();
return View::make('index')->with('htt', $htt);
}
In the View
#if(! is_null($htt))
#foreach($htt as $item)
<p>{{ $item->bassengId }}</p>
#endforeach
#endif
If you want to access data like this, you should do:
return View::make('index')->with(array('htt' => $htt));
Instead, return it like this:
return View::make('index')->with($htt);
And then, in view, access it directly:
{{ bassengId }}
You should access to the variable like this :
if(isset($htt))
{
echo $htt->bassengId;
}
or if you're using blade template :
#if(isset($htt))
{{ $htt->bassengId }}
#endif
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.
In Laravel 4, my controller uses a Blade layout:
class PagesController extends BaseController {
protected $layout = 'layouts.master';
}
The master layout has outputs the variable title and then displays a view:
...
<title>{{ $title }}</title>
...
#yield('content')
....
However, in my controller I only appear to be able to pass variables to the subview, not the layout. For example, an action could be:
public function index()
{
$this->layout->content = View::make('pages/index', array('title' => 'Home page'));
}
This will only pass the $title variable to the content section of the view. How can I provide that variable to the whole view, or at the very least the master layout?
If you're using #extends in your content layout you can use this:
#extends('master', ['title' => $title])
Note that same as above works with children, like:
#include('views.subView', ['my_variable' => 'my-value'])
Usage
Then where variable is passed to, use it like:
<title>{{ $title ?? 'Default Title' }}</title>
For future Google'rs that use Laravel 5, you can now also use it with includes,
#include('views.otherView', ['variable' => 1])
In the Blade Template : define a variable like this
#extends('app',['title' => 'Your Title Goes Here'])
#section('content')
And in the app.blade.php or any other of your choice ( I'm just following default Laravel 5 setup )
<title>{{ $title or 'Default title Information if not set explicitly' }}</title>
This is my first answer here. Hope it works.Good luck!
I was able to solve that problem by adding this to my controller method:
$title = 'My Title Here';
View::share('title', $title);
$this->layout->title = 'Home page'; did not work either.
Simplest way to solve:
view()->share('title', 'My Title Here');
Or using view Facade:
use View;
...
View::share('title', 'My Title Here');
It appears as though I can pass variables to the entire layout using attributes on the layout object, for example to solve my problem I was able to do the following:
$this->layout->title = 'Home page';
class PagesController extends BaseController {
protected $layout = 'layouts.master';
public function index()
{
$this->layout->title = "Home page";
$this->layout->content = View::make('pages/index');
}
}
At the Blade Template file, REMEMBER to use # in front the variable.
...
<title>{{ $title or '' }}</title>
...
#yield('content')
...
if you want to get the variables of sections you can pay like this:
$_view = new \View;
$_sections = $_view->getFacadeRoot()->getSections();
dd($_sections);
/*
Out:
array:1 [▼
"title" => "Painel"
]
*/
Following is simple solution worked for me.
In layout
<title>#yield('Page-Title') </title>
In your blade file
#section('Page-Title')
My Page Title
#endsection
just try this simple method:
in controller:-
public function index()
{
$data = array(
'title' => 'Home',
'otherData' => 'Data Here'
);
return view('front.landing')->with($data);
}
And in you layout (app.blade.php) :
<title>{{ $title }} - {{ config('app.name') }} </title>
Thats all.
You can try:
public function index()
{
return View::make('pages/index', array('title' => 'Home page'));
}
$data['title'] = $this->layout->title = 'The Home Page';
$this->layout->content = View::make('home', $data);
I've done this so far because I needed in both the view and master file. It seems if you don't use $this->layout->title it won't be available in the master layout. Improvements welcome!