How to display dynamic navigation bar from blade template - php

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

Related

How to create dynamic URLs at the base URL of a CMS?

I'm displaying user profiles on a PHP website using usernames as part of the URL that links to the given user profile.
I can achieve this through a controller, the ProfileController, but the URL will look like this thewebsite.com/profile/show_profile/ANYUSERNAMEHERE
What i want is something similar to Facebook, where the username is appended just after the base URL:
https://www.facebook.com/zuck
I tried passing a variable to the Index function (Index()) of the home page controller (IndexController), but the URL becomes thewebsite.com/index/ANYUSERNAMEHERE and the base url thewebsite.com throws an error:
Too few arguments to function IndexController::index(), 0 passed and exactly 1 expected.
The home page controller:
<?php
class IndexController extends Controller
{
public function __construct()
{
parent::__construct();
}
// IF LEFT, THE VARIABLE $profile THROWS AN ERROR AT THE BASE URL
public function index($profile)
{
/** AFTER REMOVING THE $profile VARIABLE ABOVE AND THE 'if'
* STATEMENT BELOW, THE ERROR THROWN AT THE BASE URL VANISHES AND
* THE WEBSITE GOES BACK TO IT'S NORMAL STATE. THIS CODE WAS USED
* TRYING TO RENDER THE URL thewebsite.com/ANYUSERNAMEHERE BUT IT
* ONLY WORKS WITH thewebsite.com/index/ANYUSERNAMEHERE
*/
if (isset($profile)) {
$this->View->render('profiles/show_profile', array(
'profiles' => ProfileModel::getSelectedProfile($profile))
);
} else {
$this->View->render('index/index', array(
'profiles' => ProfileModel::getAllProfiles()));
}
}
The profile controller:
<?php
class ProfileController extends Controller
{
public function __construct()
{
parent::__construct();
Auth::checkAuthentication();
}
public function index()
{
$this->View->render('profiles/index', array(
'profiles' => ProfileModel::getAllProfiles())
);
}
public function show_profile($profile)
{
if (isset($profile)) {
$this->View->render('profiles/show_profile', array(
'profiles' => ProfileModel::getSelectedProfile($profile))
);
} else {
Redirect::home();
}
}
}
I was expecting the base URL to pass the argument (the username) to the IndexController's Index($profile) function, but the webpage throws an error and the expected result is being displayed from the wrong URL: thewebsite.com/index/ANYUSERNAMEHERE
You would need to use a router based on regular expressions, like FastRoute, or Aura.Router.
For example, with FastRoute you'd define and add a route to the so-called route collector ($r) like this:
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
// The /{profile} suffix is optional
$r->addRoute('GET', '[/{profile}]', 'handler');
});
where handler is just a generic name for a customizable route handler in form of a callable. For example, if you'd additionally use the PHP-DI/Invoker library, the route handler ('handler') could look like one of the following callables (at least):
[ProfileController::class, 'show_profile']
'ProfileController::show_profile'
So the complete route definition would be like:
$r->addRoute('GET', '[/{profile}]', [ProfileController::class, 'show_profile']);
$r->addRoute('GET', '[/{profile}]', 'ProfileController::show_profile');
The placeholder name (profile) corresponds to the name of the parameter of the method ProfileController::show_profile:
class ProfileController extends Controller {
public function show_profile($profile) {
...
}
}
Even though the URL would look like you want it, e.g. thewebsite.com/zuck, I imagine that the placeholder {profile} of the above route definition would come in conflict with the fixed pattern parts defined in other route definitions, like /books in:
$r->addRoute('GET', '[/books/{bookName}]', 'handler');
So I suggest to maintain a URL of the form thewebsite.com/profiles/zuck, with the route definition:
$r->addRoute('GET', '/profiles/{profile}', 'handler');
I also suggest to read and apply the PHP Standards Recommendations in your code. Especially PSR-1, PSR-4 and PSR-12.

Include different variables in some views passing through controller

I'm new of Laravel and I have started my first project (with Laravel 5.7).
I have some variables that I would like to use in every single view.
In general I create, for example, a config.php file where I put my variables and use them in every pages (obviusly including config.php in all pages).
But, with Laravel, where can I put this variables? And how can I do to use them in all views?
This is my web.php:
Route::get('/task','TaskController#index');
Route::get('/task/insert','TaskController#setInsertTask');
Route::get('/task/list','TaskController#getTaskList');
And in the TaskController:
class TaskController extends Controller
{
public function index(){
return view('task.index');
}
public function setInsertTask(){
return view('task.insert');
}
public function getTaskList(){
return view('task.list');
}
}
Now I have tried to put the variables in the TaskController like this:
class TicketController extends Controller
{
private $titlePage1 = "Task manager";
private $titlePage2 = "Task manager insert";
public function index(){
return view('task.index',[
'titlePage' => $this->titlePage1
]);
}
public function setInsertTask(){
return view('task.insert',[
'titlePage' => $this->titlePage2
]);
}
public function getTaskList(){
return view('task.list',[
'titlePage' => $this->titlePage1
]);
}
}
And in the view I have insert something like this:
#extends('layout.layout')
#section('content')
<h1>{{ $titlePage }}</h1>
#endsection
But I don't think that is the best solution and I don't like it.
In this project I would like to use this variable beacuse:
1. I would like to managed three different software related each other (ex. Login for users, login for admin, login for technicians) thet they have the same database and the single area is small. So, for each area I'll liked to print a different title.
2. In the pages there are some static word, so I will create an array with all words in such a way to concenter all static words.
3. Like the title page, I would like the same things with a menu. Different menus for different areas managed in a single file in php (not in the html).
4. The same variables I will like to use them in other controllers.
I have searched a lot but I can't find which is the best practise to include a general variable in some views.
Can anyone help me? Thanks a lot.
You can share variables for all views with View::share in AppServiceProvider
I had answered in another question. For details visit this: link
Yes, you can use the variables defined in the .env at route
for example in .env
name=test
You can get it as env('name')
read here
You can do it using BaseController
class BaseController extends Controller
{
public function __construct()
{
$titlePage1 = "Task manager";
$titlePage2 = "Task manager insert";
View::share(['titlePage1' => $titlePage1, 'titlePage2' => $titlePage2 ]);
}
}
You can access it in any view {{$titlePage1}} and {{$titlePage2}}
You can also perform same thing with AppServiceProvider
In boot() of AppServiceProvider, add following code.
public function boot() {
$titlePage1 = "Task manager";
$titlePage2 = "Task manager insert";
View::share(['titlePage1' => $titlePage1, 'titlePage2' => $titlePage2 ]);
}

Yii2 Set page title from component view

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.

Laravel 3, render only one section (for ajax)

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();
}

Zend redirect within view helper

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.

Categories