Yii2 Set page title from component view - php

I have page, for example, /about.
In page's view i may set page title: $this->title = "abc" - it works ok.
Also i have Header component in /components with his own view /components/views/Header.php
How could I change my page title from my component's view?
$this->title does not work because I'm in component's view, not page.

Not sure how you are calling your component, but to change the title you need to specify you want to change the current view.
Here is an example, in the view add something like (or use any method you already used but make sure you insert the view as a parameter):
MyComponent::changeTitle($this);
And in your component (whatever method you want to do this):
public static function changeTitle($view)
{
$view->title = 'changed';
}
If this is not related with your situation, please add an example of the view and the component so we can understand better what is the scenario.

Embed the page object into the component. Then change the properties of the page object through the aggregation composition.
The component class would read something like...
class MyComponent extends Component
{
private $pageObject;
public $title;
public function __construct(yii\web\View $view)
{
$this->pageObject = $view;
}
// this would change the title of the component
public function setTitle(string $newTitle)
{
$this->title = $newTitle;
}
public function changePageTitle(string $newTitle)
{
$this->pageObject->title = $newTitle;
}
}
Where, if you're in a view and you want to use your component in that view, you can instantiate it using
$comp = new MyComponent($this);
// where `$this` is the current page object
Now, from the component scope, $this->title = 'bleh'; would change the title of the component while $this->changePageTitle('bleh'); would change the page's title.

Related

How to display dynamic navigation bar from blade template

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,
]);
}

One Method Controller, Multiple View, Codeigniter

So, lets say I have a global view and specific view.
In global view, the url may look like this (http://example.com/index.php/controller/method/)
Where when it come to the specific page view, the url will turn like this:
(http://example.com/index.php/controller/method/1989-03-25)
The difference between the global view and the specific page view is, if in the global view it shows the information in general, but in the specific page view it shows based on the detail or the date.
Of course, not only have different view, but also they will have different function of models.
The point is, I just want to make the url keep in order (which it mean there is no change in the name of the controller method).
How to do this. Thanks in advance.
You create just one param into your function. And set the param value is null. like this
class YOUR_CLASS extends CI_controller {
public function method($params=null) //null is Empty value
{
if($params)
{
//load your modal and view with your param
}
else
{
//load your modal and view
}
}
}
This method supports the following type of URL's without any issue.
http://example.com/index.php/YOUR_CLASS/method/
http://example.com/index.php/YOUR_CLASS/method/1989-03-25
Hope this will help you....
This class used to wrap CI_controller, my_base_controller will override CI_controller methods for depends to your project needs
class my_base_controller extends CI_controller {
}
You can load models by known states and define it in my_base_controller class.
class my_controller extends my_base_controller{
public function method($params=null) //null is option value
{
}
}
Good luck!
You can add additional parameter in your method like:
class Your_controller extends CI_controller {
public function method($params = null)
{
// Your Code Here with the condition for processing of the $params variable
}
}
in which that $params can be something in your URL like:
http://example.com/controller/method/your-dynamic-params
So if the $params is null you will call the model the views the general and if the $params has a specific value you can call other model by using if or switch conditional statements. Hope this helps...
Update with Example
you can use the $params variable like this:
if ($params == "1991") {
$this->load->view('general.html', $params);
} elseif ($params == "1992") {
$this->load->view('year_1992.html', $params);
} else {
$this->load->view('other_years.html', $params)
}
in this way you can use the $params as a conditional variable to load different views.
or using switch:
switch($params) {
case '1991':
$this->load->view('general.html', $params);
break;
case '1992':
$this->load->view('year_1992.html', $params);
break;
default:
$this->load->view('other_years.html', $params)
}
Note: Use a helper method so you can avoid fat controllers because it will be hard to test your methods if you have a several lines of codes in a function.

Pass Database Values to Layout

In my Zend application there is a layout file used in multiple modules. Now i need to retrieve data from database (table gateway) and display on layout. Then it should appear across all the modules.
How do i achieve that ?
Ex -
<?php echo $user_name; ?>
Value for $user_name should be taken from database and pass to layout file.
you dont have to set it in every controller. You could just attach it to a layout variable in your module.php.
public function onBootstrap(MvcEvent $e)
{
$sm = $e->getApplication()->getServiceManager();
$tableWhatever = $sm->get('tableWhatever');
$viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
$viewModel->userName = $tableWhatever->getUserName();
}
Depending on the zf2 version you may have to access the variable in your layout like so:
$this->layout()->userName;
You also have the possibility to extend the AbstractActionController and add the layout variables trough that. I usually just go with the quick onBootstrap method though.
I believe, in Zend, your controller(s) will want:
$this->view->assign('variableName', 'variableValue');
And in your view(s), you will want:
$this->variableName;
You could use Zend Plugin to achieve something like that, like:
class MyPlugin extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
// Get instance
$layout = Zend_Layout::getMvcInstance();
$view = $layout->getView();
$view->user_name = 'your_username';
}
}
and register your plugin in frontController:
Zend_Controller_Front::getInstance()->registerPlugin(new MyPlugin());
then in layout , you could do:
<?php echo $this->user_name; ?>

Zend passing data to other view

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]');

sending data from action helper to partial view

i want to send some data from Action Helper to view Partial and i am unable to do it, to get the clear picture. here is all the related code i am using.
in my layout.phtml i am using this placeholder. to generate onDemand navigation menu.
<?php echo $this->placeholder('action-navigation'); ?>
so when i need it in my controller or action method i can simply place use this code.
$this->_helper->navigation()->renderActionNavigation();
The Action helper i am using is.
class Zend_Controller_Action_Helper_Navigation extends Zend_Controller_Action_Helper_Abstract
{
private $_view = null;
public function direct()
{
$this->_view = $view = Zend_Layout::getMvcInstance()->getView();
$this->_view->placeholder('action-navigation');
return $this;
}
public function renderActionNavigation()
{
$config = new Zend_Config_Xml(
APPLICATION_PATH.'/configs/navigation.xml', strtolower(
$this->getRequest()->getControllerName().
$this->getRequest()->getActionName()
)
);
$container = new Zend_Navigation($config);
// here i want to send $container to _action-navigation.phtml.
$this->_view->addScriptPath(APPLICATION_PATH.'/layouts/')->render('partials/_action-navigation.phtml');
}
}
this is my view partial _action-navigation.phtml
$this->placeholder('action-navigation')->captureStart();
//i want to get zend_navigation instance. from the above action helper here.
$this->placeholder('action-navigation')->captureEnd();
i have problem sending data from action helper to partial view _action-navigation.phtml how do i do it?
Thank you.
Use partial() instead of render():
$this->_view->partial('partials/_action-navigation.phtml', array('nav' => $container));
And in your partial:
$this->nav // to get your container

Categories