I'd like to reuse my templates and would like to return only one rendered section as an ajax response (html table) which belongs to the "content" section (index.blade.php).
#section('content')
html...
#endsection
I've created another layout called ajax (ajax.blade.php) which contains only:
#yield('content')
My controller:
class Some_Controller extends Base_Controller {
public $restful = true;
public $layout = 'layouts.main';
public function get_index (){
if ( Request::ajax() )
$this->layout = 'layouts.ajax';
$view = View::make('some.index')->with('data', 'shtg');
$this->layout->content = $view;
}
}
It works when I request the route via normal GET request... but when I request it via ajax I get an error:
Attempt to assign property of non-object
on the line containing
$this->layout->content = $view;
I've also tried
return Section::yield('content');
Which returns empty document.
Is there a way to return rendered section? I've searched over the forums and couldn't find anything apart from:
http://forums.laravel.io/viewtopic.php?id=2942
Which uses the same principle and doesn't work for me (I've tried all the variations mentioned on the link above).
Thanks!
You appear to be mixing blade templates with controller templates. If you wish to use controller layouts (my preference) then remove the #section('content') and #endsection, and replace #yield('content') with $content.
However, that is not your entire problem. The following line is picked up by the layout method and converted into a real view...
public $layout = 'layouts.main';
You could easily extend the layout function in your controller, adding a layout_ajax attribute like this...
/**
* The layout used by the controller for AJAX requests.
*
* #var string
*/
public $layout_ajax = 'layouts.ajax';
/**
* Create the layout that is assigned to the controller.
*
* #return View
*/
public function layout()
{
if ( ! empty($this->layout_ajax) and Request::ajax() )
{
$this->layout = $this->layout_ajax;
}
return parent::layout();
}
Related
I have a navigation bar stored in the database, and I have a Controller witch lists the navbar for my template file.
$navbar=/*Query*/
return view('inc.template')->with('nav',$navbar);
I have other pages where I want to use the template with the navigation bar of course, but when I extend the template I get error message 'Undefined variable $nav'. I understand why I get this error message, because I don't returned the variable for the other page. So I need solution for this.. every idea is welcome!.
I have single product page, where I want to include the template with the navigation bar and also I will list the Single Product here.
I know I can copy the query code and paste it to the single product controller, but I believe this is not a good solution (repeating myself).
Thanks in advance for your ideas!
You need to check the View Composer which will help you do what you want : https://laravel.com/docs/8.x/views#view-composers (use the correct Laravel version).
In order to do this, you will need to create a new class that will be your view composer and then register it to the container of Laravel.
In your case, that would be something like this :
<?php
namespace App\Http\View\Composers;
use Illuminate\View\View;
class NavbarComposer
{
/**
* Create a new navbar composer.
*
* #return void
*/
public function __construct()
{
// If you need to do something when instanciating this view composer
}
/**
* Bind data to the view.
*
* #param \Illuminate\View\View $view
* #return void
*/
public function compose(View $view)
{
// here you can add as many variables that your navbar might need
// first parameter is the name of the variable and second the value.
$view->with('navbarData', []);
}
}
To register your view composer you can then do something like this :
View::composer('profile', ProfileComposer::class);
Maybe take a tour to https://www.laracasts.com to learn the basics of Laravel because that's not how to use routes.
I don't really understand your code, but I think this may help you:
If you want to get the variable in your non-yield blades, you can share your variable from controller's constructor, so don't need to add that in all methods. Just add this constructor method in your controller-class like this:
// ADD THIS >>>
public function __construct()
{
View::share('data', 'example');
}
// <<<
// YOUR EXISTING METHOD >>>
public function index()
{
return view('navbar');
}
// <<<
Now you can access $data variable in your blade, which are used in your appropriate page.
Don't forget to use this class in the top of controller's class:
use Illuminate\Support\Facades\View;
The simple answer is: you just need to return everything that belongs to your home.blade.php in the index function of the HomeController. You should do something like this:
public function index(){
$navbar = "Your query to get navbar data";
return view('home',[
'navbar' => $navbar
]);
}
Then call the navbar data into your home.blade.php ( or into the actual navbar.blade.php ) by using foreach.
Note: If you want to call the navbar in multiple views just call the navbar data from all the view returning functions as like index function.
UPDATE
To achieve that you can just do something as:
public function index(){
$navbar = "Your query to get navbar data";
if(count($navbar) == 0){
$navbar = "";
}
$slider = "Your query to get slider data";
if(count($slider) == 0){
$slider = "";
}
return view('home',[
'navbar' => $navbar,
'slider' => $slider,
]);
}
I'm looking at the Laravel docs, and I see this snippet:
class UserController extends BaseController {
/**
* The layout that should be used for responses.
*/
protected $layout = 'layouts.master';
/**
* Show the user profile.
*/
public function showProfile()
{
$this->layout->content = View::make('user.profile');
}
}
we can clearly see that $this->layout = 'layouts.master'. However, then they define a child of the layout object (which as I understand is only a base PHP string, and does not have a field called content, via ...
$this->layout->content = View::make('user.profile');
How can a string have a field called content defined?
when I subclass BaseController and try to assign a value to
$this->layout->content, why do I get the following error: "Attempt
to assign property of non-object"?
Why not look at BaseController? It looks like they change $this->layout.
https://github.com/laravel/laravel/blob/master/app/controllers/BaseController.php
<?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);
}
}
}
My advice, if you use a PHP framework, don't be afraid to check its source when you don't understand why it works. There is usually much less "magic" than you think...
IMO, this seems like a bad design though, to initialize the variable as a string and then change it to be some object. Kind of just abusing the loose typing.
I've tried many solutions that had the same questions like mine. But didn't found a working solution.
I have a controller:
event.php
And two views:
event.phtml
eventList.phtml
I use eventList to get data via ajax call so I want to populate both views with a variable named "eventlist" for example.
Normally I use this code for sending a variable to the view:
$this->view->eventList = $events;
But this variable is only available in event.phtml.
How can I make this available for eventlist.phtml? (without adding a second controller)
Edit:
I get this error now
Call to undefined method Page_Event::render()
Function:
private $_event;
public function init(){
$dbTable = new Custom_Model_DbTable_Events();
//Get Events
$this->_event = $dbTable->getEntries($this->webuser->businessId);
$this->index();
}
public function indexAction(){
$this->eventList = $this->_event;
$this->render();
$this->render('eventlist');
}
If I use $this->view->render('event.phtml') and eventlist.phtml it won't pass the data
I'm using zend version 1
You can pass variables to other views using render()
public function fooAction()
{
// Renders my/foo.phtml
$this->render();
// Renders my/bar.phtml
$this->render('bar');
}
Copy and paste this in your controller and rename your controller from event.php to EventController.php
class EventController extends Zend_Controller_Action
{
private $_event;
public function init(){
$dbTable = new Custom_Model_DbTable_Events();
//Get Events
$this->_event = $dbTable->getEntries($this->webuser->businessId);
$this->index();
}
public function indexAction(){
// You're calling the index.phtml here.
$this->eventList = $this->_event;
$this->render('event');
$this->render('eventlist');
}
}
To specify that only written #Daan
In your action:
$this->view->eventList= $events;
$this->render('eventList'); // for call eventList.phtml
In you View use : $this->eventList
You could render it within the view itself (eventList.phtml), rather than within the controller, using the same line of code you used above:
$this->render('event[.phtml]');
I tried almost everything but I just cant get the following to run.
<?php
class BaseController extends Controller {
// Define frontpage layout manager
protected $layout = '';
public function __construct() {
parent::__construct();
$theme = Theme::where('enabled', '=', true)->first();
// HERE !! : This never changes the value of $layout class var
$this->layout = View::make('themes.front.' . $theme->folder . '.master');
// I also tried without View::make(..)
// I also checked that $theme returns something and it does return a theme
}
/**
* Setup the layout used by the controller.
*
* #return void
*/
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
}
}
}
I simply cannot change the value of $layout in my constructor. I need this to allow user to switch between layouts.
So what I wanted to achieve with this is: I would have multiple layouts (templates) and I would allow user to change these templates via administration so I needed a quick and easy way to manipulate the protected $layout value.
The problem with putting my code in __constructor() {} is that setupLayout() will override it and thus the error as no layout is found.
So there are two solutions:
1) Declare layout in each sub-controller
Meaning each controller that extends your base controller defines it's own protected $layout in it's own __constructor() {} method. However this is very repetitive if all your pages share the same template.
2) Maniuplate the setupLayout() method
Since all my pages share the same layout and I know for certian there will always be at least one template I was able to simply alter the setupLayout() method to:
function setupLayout()
{
$theme = Theme::where('enabled', '=', true)->first();
$this->layout = 'themes.front.' . $theme->folder . '.master';
}
Hi i have a following script to redirect within view helper
<?php
class Application_View_Helper_ExistUserRev extends Zend_View_Helper_Abstract{
public function existUserRev($params,$user)
{
$businessReviewMapper = new Application_Model_Mapper_BusinessReviewsMapper();
$businessReviewModel = new Application_Model_BusinessReviews();
$result = $businessReviewMapper->userReviewStatus($user>getUserId(),$params['bzid']);
if($result){
$url = 'http://www.akrabat.com';
$this->_helper->redirector->gotoUrl($url);
}
}
}
?>
But it seems that my above redirect seems not working. How can i redirect within view helper of my zend app? Thanks
As you're in a View Helper class, you can't use $this->_helper->redirector->gotoUrl($url);, this is an Action Controller function.
You have to call the redirector in your View Helper.
Try this :
$_redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$_redirector->gotoUrl($url);
Redirector is a controller ACTION helper, not a View helper, so you should use it from the controller, not from the view.
To redirect from the view (not a good idea BTW, the logic should stay in the controller, not in the view), try using the Zend Action View Helper
This is even simpler then presented so far:
Excerpt from Zend Framework 1.x reference: Writing Custom Helpers
In general, the class should not echo or print or otherwise generate
output. Instead, it should return values to be printed or echoed. The
returned values should be escaped appropriately.
Basically a view helper should return a value, not perform an action.
Action helpers on the other hand can do pretty much anything you need done.
Here is a very simple example to demonstrate the form of using the direct() method in the helper:
<?php
/**
* Simply returns a search form to a placeholder view helper
*
*/
class My_Controller_Action_Helper_Search extends Zend_Controller_Action_Helper_Abstract
{
/**
* #param string $action
* #param string $label
* #param string $placeHolder
* #return \Application_Form_Search
*/
public function direct($action, $label = null, $placeHolder = null)
{
$form = new Application_Form_Search();
$form->setAction($action);
$form->search->setLabel($label);
$form->query->setAttribs(array(
'placeholder' => $placeHolder,
'size' => 20,
));
return $form;
}
}
here is how it's used in a controller to populate a placeholder helper in either a view script or a layout.
public function preDispatch()
{
$this->_helper->layout()->search = $this->_helper->search(
'/index/display', 'Search My Collection!', 'Search Query'
);
}
and in the view script or layout:
<?php echo $this->layout()->search?>
In your case you might use an action helper to establish the values needed to construct the proper url, then you could pass those value to the url() helper or to a helper of your own construction.