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 ]);
}
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,
]);
}
Thanks for watching my first question.
I have something confused.
How could I write the operations of database into database and don't write the function in every Controller?
I have considered middleware and find that must change my route register style.
my Route is this:
Route:resource('province','\\Modules\\Info\\Controllers\\P_ProvinceController');
Dose it has some awesome methods replace this?
public function Store(Request $request)
{
$params = $request->input('data');
$params['CreateID'] = Auth::user()->id;
$params['CreateName'] = Auth::user()->name;
$params['CreateTime'] = Carbon::now();
$province = P_ProvinceModel::Create($params);
$params['Pro_Is_Del'] = 1;
$log_info['table'] = $province->getTable();
$log_info['type'] = "create";
$log_info['user'] = Auth::user()->name;
$log_info['datetime'] = Carbon::now();
LogModel::create($log_info);
if($province){
return response()->json(array(
'status' => 200,
'msg' => '新增成功',
'data' => $province
));
}else
return response()->json(array(
'status' => 500,
'msg' => '保存失败',
));
}
Thanks.
Here is how I solved across model functionality
First Create a Trait that does what you want on save.
<?php
namespace App\Models\Observers;
trait CreatedByObserver
{
public static function bootCreatedByObserver(){
/** Simply means that whenever this model is creating a model do: */
static::creating(function($model){
if(auth()->check()){
$responsiblePerson = auth()->user()->first_name . " " . auth()->user()->last_name;
} else {
$responsiblePerson = "system";
}
/** You can set any model variables within */
$model->created_by = $responsiblePerson;
});
}
}
In there do all you need to do when a record is saved/created/updated/deleted
Then In all Models you want this behaviour used add the trait.
Check them out here : https://laravel.com/docs/5.2/eloquent#events
As far i understand your question, you are asking for way to make your controller an abstract type, i.e. controller just need to handle the route and view not any other things(like database,application logic etc) which is the philosophy of the laravel Framework.
To make your controller abstract (meaning of abstract as explained aboave),
first you need to understand, "What your application logic are and what your database logic are ?"
when you understand these two things then, you can easily separate your aapplication logic and databasse logic from your controller.
For example :
For keeping your Application logic you can make service folder in your root of your project also you can make folder name 'Dao' (Database access object) in the same path of service . You need to keep these folder in autoload from your composer. Just make class for service and your Dao.
And now your application follow will be,
First Route, will hit controller then controller will need to call some method in service and then service will call the respective DAO . method.
Example :
Controller/YourController.php
Class YourController extends Controller {
public function Store(Request $request,yourservice,$yourService)
{
$this->myservice = $yourservice;
$this->myservice->store('your inputs request');
return $something ;
}
}
service/yourService.php
Class yourService {
public function store($yourinputs,yourDao $mydao){
$this->mydao = $mydao;
//you can use your application logic here
return $this->mydao->create($yourinputs);
}
And now the turn is for DAO :
dao/yourdao.php
use model // use your model here .
class yourDao {
public function create($yourdata,yourmodel $model){
$this->model = $model;
return $this->model->create($yourdata);
}
}
Now, you can see the controller just save the data in database, but don't know how it is saving the data and what are the application logic.
This explanation is just a simple way of doing project to make a controller abstract. There are other various ways of doing this. For example you can see Repository Design Pattern , which also used by laravel core .
Hope this explanation will not bore anyone . :) Happy coding .
I want to share this data to all views with laravel 4.2
But, can I use array to pass this 2 data with View::share()?
class Sidebar extends BaseController {
public function __construct() {
$package_sidebar = TravelPackage::orderBy('idTravelPackage','DESC')->take(4)->get();
$artikel_sidebar = Artikel::orderBy('date','DESC')->take(4)->get();
View::share()
}
}
Put this in your routes.php or somewhere else more appropriate:
<?php
View::share('package_sidebar', TravelPackage::orderBy('idTravelPackage','DESC')->take(4)->get());
View::share('artikel_sidebar', Artikel::orderBy('date','DESC')->take(4)->get());
Then you'll be able to reference $package_sidebar and $artikel_sidebar in any view.
I am using cakephp-2.x. I have one function name user_info() in the UsersController.php i want to access this in another controller name MessagesController.php
Code -
UsersController.php
public function user_info(){
$user_id=$this->Session->read('Auth.User.id');
$data=$this->User->findById($user_id);
$this->set('user_info',$data);
}
MessagesController.php
public function index(){
//$userInfo=new UsersController();
//$userInfo->user_info();
$this->user_info();
pr($data);
}
Error Message-
Fatal Error
Error: Call to undefined method MessagesController::user_info()
File: E:\xampp\htdocs\2014\myshowcam\msc\app\Controller\MessagesController.php
Line: 18
Notice: If you want to customize this error message, create app\View\Errors\fatal_error.ctp
Typically if you're trying to access a function in one controller from another controller you have a fundamental flaw in your project's logic.
But in general object usage is thus:
$otherController = new whateverMyControllerNameIs();
$otherController->functionName();
However I'm not familiar enough with cake to tell you the pitfalls of doing such a thing. For example I have no idea what this would do to routes or what other variables/objects are required to initialize a controller correctly.
EDIT:
Ref: CakePHP 2.3.8: Calling Another Controller function in CronController.php
App::import('Controller', 'Products'); // mention at top
// Instantiation // mention within cron function
$Products = new ProductsController;
// Call a method from
$Products->ControllerFunction();
Try requestAction function of cakephp
$result = $this->requestAction(array('controller' => 'users', 'action' => 'user_info'));
Why would a simple, When can complicated?
All the information for a registered user of User model is accessible in the following manner:
AppController.php
public $user_info; /* global scope */
public function beforeFilter(){
$this->user_info = $this->Auth->user(); // for access user data in any controller
$this->set('user_info_view',$this->Auth->user()); // for access user data in any view or layout
}
MessagesController.php
public function index(){
debug($this->user_info);
$my_messages = $this->Message->find('all',
array('conditions' => array('Message.user_id' => $this->user_info['id']))
}
....
layout or view.ctp
<?php echo $user_info_view['name']; ?> // email, etc
Why not take advantage of the way CakePHP handles relationships? There's a very easy way to achieve what you're trying to do without extending controllers or loading in additional controllers which seems excessive for your example.
Inside AppController's beforeFilter()
Configure::write('UserId', $this->Session->read('Auth.User.id'));
This will allow you to access the UserID from your models
Inside your User's model, create the following function
/**
* Sample query which can be expanded upon, adding fields or contains.
*
* #return array The user data if found
*/
public function findByUserId() {
$user = $this->find('first', array(
'conditions' => array(
'User.id' => Configure::read('UserId')
)
));
return $user;
}
Inside your Users controller (Minimal is better, no?)
public function user_info() {
$this->set('user', $this->User->findByUserId());
}
Inside your Messages controller
public function index() {
$this->set('user', $this->Message->User->findByUserId());
// --- Some more stuff here ---
}
And that's it, no need to be extending controllers, just make sure your Message and User model are related to each other, failing that you can bindModel or use ClassRegistry::init('User')-> for example.
I have a controller in my Laravel project called ImageController. This is a pretty basic CRUD controller.
When I access /images/{id} through my ImageController#show action, I want to also display comments. However, I don't want to put the comment logic in my ImageController. For this logic, I have created an ImageCommentController.
I'm not really sure how to go about this, but I'm trying to do something of this sort:
class ImageController extends BaseController {
// methods ...
public function show($id)
{
$images = // get images ...
$this->layout->view = // images.show and imagescomment.index (using ImageCommentsController#index logic)
}
}
I'm sorry if this is vaguely phrased, let me know if it is and I'll try to make it more understandable.
Maybe a better solutions than using a Controller for displaying the comments is to use a class with a method renderComments() that basically does something like:
class Comments {
public static renderComments($commentType = 'images')
{
$comments = Comments::where('comment_type', '=', $commentType)->get();
return View::make('comments', $comments)->render();
}
}
Then for example inside your image view:
...
{{ Comments::renderComments() }}
...