This may be a dumb question, but I've started exploring Laravel Breeze with vue and I'm not sure how to manage resources and their views. (Using Laravel 9)
For example, if I have a table 'members' and a resource controller 'MemberController', ordinarily in the web.php file I would do something like:
Route::resource('members', MemberController::class)->names('members');
Then I'd create a 'member' folder in my resource/views folder to store the views for that table. I could then call the view from the MemberController something like:
public function index()
{
$members = Member::all();
return view('member.index', compact('members'));
}
I'm trying to do something similar using vue in breeze, so I guess I'd have the vue pages in the 'resources/js/Pages' folder. But this didn't seem to work properly.
I don't know how to transition from the previous approach of handling resources and views to Breeze using vue.
What's the recommended way to handle resources in an SPA with Breeze/vue?
After following Djave's suggestion, I took a look at the sample app from inertia.js and that answered everything.
The problem I had was due to using the dot notation when specifying the path to the vue page. So, in my example above, it should instead be like this:
return view('Member/Index', compact('members'));
The inertia sample app code has a lot of good examples!
Related
This is my long quest to develop web apps using core PHP and follow the best possible practices and not using a framework. I have achieved many things by structuring my project a better way. However ...getting a clean URL is often a problem for large apps.
Till now...I have used the Slim Framework only for creating RESTFUL services outside my web apps.
I am using Slim Framework to create APIs for a PHP project. Now, I have an install of Slim up and running fine. I have my routes talking to the database and doing what they're supposed to do, generally. My question has to do with modularizing the code. At the moment, all my routes are defined in my index.php file in the root directory. I would very much like to separate these out, say into a /controllers folder.
As I liked the way Slim makes pretty good URLs...I am wondering if it is possible to use Slim as my app architecture ...and let all my pages or APIs be accessible through the Slim index.php.
Yes pretty easily here are the steps I have taken on a recent project.
First lets say your have a HomeActionController
class HomeActionController {
//The below line I have moved into an abstract Controller class
public $view = null;
//This is using Slim Views PhpRenderer
//This allows for a controller to render views can be whatever you need
//I did not like the idea of passing the whole DC it seemed overkill
//The below method I have moved into an abstract Controller class
public function __construct(\Slim\Views\PhpRenderer $view = null){
if($view != null){
$this->view = $view;
}
}
//View could be any action method you want to call it.
public function view(Request $request, Response $response, array $args){
$data['user'] = "John Doe";
return $this->view->render($response, 'templates/home.php', $data);
}
}
Now you need to be able to call an instance of this controller from a route so you need to add the controllers you have to the DC
Where ever you are creating your instance of slim you will need to get the DC and add an instance of your controller:
$app = new \Slim\App($config['slim']);
// Get Dependency Container for Slim
$container = $app->getContainer();
$container['HomeActionController'] = new Controller\HomeActionController($container['view']); //Notice passing the view
As a note the above instantiations could have been a closures but I did not see the point at the time or making them. Also, there are ways to lazy load that I have not explored yet see here for more information.
Now the last thing you need to do is be able to call these on the routes which is not a huge challenge.
$app->get('/home', 'HomeActionController:view');
Granted you cannot have an action with parameters but I have not had an issue just passing them along in the request and then getting them from there.
If you want to create a app with no framework, then i would recommend looking through this small github repo:
https://github.com/PatrickLouys/no-framework-tutorial
It goes through with you settings everything up in terms of routing, plus would make everything go through the index.php in a public folder like your asking.
I would like to add a new phtml file to my index folder in which I already have several views:
index
landing
And so on... I access them by using the following logic:
sitename.com/index/landing
or
sitename.com/index/index
How can I add the phtml file (my new view) to my index folder so that I'm able to see it when I enter in the browser:
sitename.com/index/mynewview
I'm quite new to the whole Zend Framework, and I'm not sure how the structure works exactly, so I'd like to find out more. Can you guys help me out with this, how am I supposed to do this?
Thanks heaps! :)
P.S. The views are in the following directory structure:
module/application/view/application/index/
and then here are all of the views, this is where I'd like to add my new view and access it from browser like this:
/index/testview
Edit:
When I add the testview.phtml to the index directory and put some test tags like this in it:
<h1> Testing new view page </h1>
It's not being rendered on the browser
Because this is an MVC framework, you're skipping a few steps. You're probably going to get a few harsh responses, but I'll try to fill in the holes for you very quickly.
Ignore the file folder structure for a minute.
This is a route:
/index/landing
Routes point to Actions inside of Controllers to work.
Assuming you have started with the skeleton, open up your module's module.config.php, you should see route config, e.g.:
https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php#L29
You'll need to add a config entry for the routes you want to serve. It could be as simple as a Literal entry for /index/landing, or something more complex (Segments, Regex, etc.) that handle patterns for routing. Spend some time tinkering and learning here; routes are pretty critical to working with MVC.
When configuring the route, the assumption is that you have a Controller set up, and that this Controller has an Action (to which your route is pointed). That Action, is where you can connect template files (phtml,twig,etc.) to routes:
// dummy action that serves index/testview
public function fooAction(){
$vm = new Zend\View\Model\ViewModel();
$vm->setTemplate('index/testview');
return $vm;
}
That index/testview, will be in your module's view templates, not in your public folder.
I think that's a reasonable primer to get you on your way!
Take some time to learn:
http://zf2.readthedocs.io/en/latest/index.html#userguide
Maybe start here:
http://zf2.readthedocs.io/en/latest/in-depth-guide/understanding-routing.html
ZF2 (V3 is coming!) is a beautiful thing, it's worth it.
Good luck.
As I am new to the laravel 4 after spending some few months in Codeigniter, I went through the lots of tutorials about laravel and one thing I want to be clear is what is the actual difference between Routes and Controller in laravel, because we can create and generate view in both controller and routes too. Will anyone explain me in brief when to use routes and Controller in laravel? Because in other Framework we need routes to specify some particular URL's within the apps and Controller were used to do some real tasks but in laravel I didnt get the main concept of Routes except the routing mechanism?
In Laravel, you can totally skip controllers and do the task of performing business logic and generating the view in the routes.
E.g I have a link b2.com/getUsers so in routes.php I can write:
Route::get('/getUsers',function()
{
$users=User::all(); //select * from users
return View::make('allUsers')->with('users',$users);
}
So, here to serve the request b2.com/getUsers, we didn't use controller at all and you can very well do this for handling all requests in your application, both get and post.
But then, if your application is large and have 500+ url's with complex business logic then imagine putting everything in one routes.php. It will totally make it criminally messy and whole purpose of architecture will be defeated. Hence what we usually do is, reserve routes.php for routing only and write all business logic (along with generation of views inside controllers)
So the same example can be solved as:
To handle link: b2.com/getUsers, in routes.php
Route::get('/getUsers', array('before' => 'auth', 'uses' => 'MyController#getUsers'));
MyController has the method getUsers defined like this:
public function getUsers()
{
$users=User::all(); //select * from users
return View::make('allUsers')->with('users',$users);
}
I usually create a controller for related activities e.g for login/signup/logout. I create AuthController and all the links related to those activities are routed to AuthController through routes.php.
The fact that you can get views or do a lot of things in Routes::any() is against MVC and separation of logic.
In Route::get("admin", function(){}), you indeed have a fast access to your route callback, which otherwise in a standard fashion must just be bound to controller. But Laravel allows you to do your job there in a closure (function(){}), instead of binding it to a controller. Anyway, it lets you, but you'd better avoid it. In Route::get() you only should go with your 'routing' and nothing more.
There is no reason for you to use callbacks in Route unless for testing or some trivial requests. So, better to avoid this:
Route::get("admin", function(){
return View::make("admin_index");
});
And rather go with this:
Route::controller("admin", "AdminController");
And in your AdminController.php :
// I mean create a file named AdminController.php in controllers directory under app.
class AdminController extends Controller
{
function getIndex()
{
return View::make("admin_index");
}
}
Read more about Route::controller and restful controllers.
Some Notes:
Having the ability to add closures in your Routes allows you to make
complex decisions on Routes and have a powerful routing system.
These callbacks let you add conditions to your route.
Having Controller separated from you Routes makes you application
more extensible, less confusing and makes other coders more
comfortable in future.
It allows you to focus better on your problem and finding solution,
this physical separation is very important. Having View::make()
inside your Route stirs all problems into each other and makes up a
confusion for the coder.
Let's see what we have in both cases:
In CodeIgniter, a route is just pointing your request to a specific method of your controller:
$route['blog/joe'] = "blogs/users/34";
Here when you visit application.com/blog/joe, you will invoke the controller BlogsController, call the method users() and pass 34 as the first parameter. Nothing else. As they put it, a route in CI is just a one-to-one relationship between a URL string and its corresponding controller class/method.
Now, in Laravel, you have a lot of possibilities:
You can directly return a simple response
You can return a view
You can point the request to a specific controller and a method
You can write some logic in a closure and then decide what you want to do
You can add some additional functionality to them, like attaching filters, checking parameters upon a regex, give them separate names, etc., but this is the main functionality.
What's the reason for being able to do so much stuff? It gives you the power to use them in any way you need. Examples:
Need a small website, rendering static HTML? Use them like this:
Route::get('/', function()
{
return View::make('greeting');
});
Need a bigger application using the traditional MVC pattern? Use like this:
Route::get('user/{id}', 'UserController#showProfile');
Need a RESTful approach? No problem. This will generate routes for all the CRUD methods:
Route::resource('photo', 'PhotoController');
Need something quick and dirty to handle a specific Ajax request? Keep it simple:
Route::post('foo/bar', function()
{
return 'Hello World';
});
TL;DR: For very simple things without or with very little logic, use them instead of controllers. Otherwise, always stick to the MVC principles and route to your controllers, so that they're the ones who do the actual work.
I am using the resource route to access several crud functions on my site but I am getting a NotFoundHttpException error when accessing one of several pages. This was working this earlier and I don't think I have changed anything.
Route::resource('/contractors', 'ContractorController');
The specific ContractorController method:
public function skills($id)
{
$contractor = Contractor::find($id);
return View::make('contractors.skills')
->with('contractor', $contractor);
}
I have all of the basic crud methods located in the ContractorController too. I am using the skills method to create a new view that edits tags in a pivot table
my url is public/contractors/1/skills and this blade view:
contractors/skills.blade.php
Do you see anything that I am doing wrong?
There's only a few routes that Resource controllers by default will handle, you can see a full list of them (7 in all) in the documentation entry for Resource Controllers.
The skills URI segment is not one of them. You will need to add a separate route for that:
Route::get('/contractors/{contractorId}/skills', 'ContractorController#skills');
However, this isn't really RESTful design. You may be better off with a separate skills resource.
Is it generally a good idea to interact with database in view layer in MVC frameworks?
I'm using Laravel 4.
I want to show some data from database at top of all website's pages.
I have a main.blade.php and: #include("inc.header")
If I should, how can I connect to database from inc/header.php in right way?
I don't want make multiple connections one here at header.php and one in my pages controllers.
I'm more familiar with PDO than Laravel's database methods and ORMs.
Any advice is appreciated!
Edit
Friends gave nice advice and answers about MVC and Laravel workflow, but my main concern is still here.
Ok I have used controllers and models to get required data, then as I said, it should be present for the view layer in every page, So should I repeat the same task to get the same data in All my controllers' actions? (I guess that's why we have Filters here! then again, is it ok to use db in Laravel filters? using a model?)
Thanks in advance :)
Never do anything more than loop thru your data in your view layer. Basically a normal MVC pattern in laravel could be something like this:
It all begins with the routing layer (which btw. is fantastic in laravel)
Using closures
Route::get('/home', function()
{
//Here data is an array, normally you would fetch data
//from your database here and pass it to the View.
$data = array('this', 'is', 'my', 'data-array');
return View::make('my.view')->with(compact('data');
});
Using controllers (and a controller method)
//the same route is bound to a controller method
Route::get('/home','HomeController#myFunction');
The controller for the above could look something like this:
<?php
class HomeController extends BaseController {
//The function you call from your route
public function myFunction()
{
$data = array('this', 'is', 'my', 'data-array');
return View::make('my.view')->with(compact('data');
}
}
The above example just shows the VC in MVC, but generally you pass data from your models in the same way.
Heres a quick one:
Model usage in controllers
public function myFunction($user)
{
$userdata = User::find($user)->orderBy('firstname', 'desc');
$infodata = Event::find(1)->course;
return View::make('my.view')->with(compact('data', 'infodata');
}
So the idea is that laravel lets you do things in multiple ways. If you have a minor app, and are sure that you can manage without controllers you could skip the controller and keep everything in your routing layer.
For most apps however the controllers are needed for controlling the dataflow in the application.
If you are totally new to MVC you should check out some tuts on the subject.
EDIT:
Ahaa! So you wanted to share some piece of data in all your views! Well thats simple. Because all your controllers extend the BaseController you can simply pass in the data in there. Like so:
class BaseController extends Controller {
public function __construct()
{
$data = array('alot', 'of', 'data');
return View::share('data', $data);
}
}
Now the data variable is available in all the views.
PS. Filters are meant to filter stuff, like to check if certain things are "ok". This could include to check authed users, or form submissions etc.
There is another solution that is especially handy for cases like yours. If you have 15 routes that all ultimately include the inc.header view... well you can see where this is going. You'll have data logic repeated in several places. Patrik suggested using the BaseController which is a good solution but I prefer to use a composer.
View::composer('inc.header', function ($view)
{
$view->some_data = MyModel::where(...)->get();
});
It doesn't get much easier then that. :)
Is it generally a good idea to interact with database in view layer in MVC frameworks?
No, you don't interact with your database (model) in your view layer. MVC stands for "Model View Controller" to separate logic, application data and business rules of your application.
If I should, how can I connect to database from inc/header.php in right way?
I don't want make multiple connections one here at header.php and one in my pages controllers.
You could create a main layout (containing your header) and use this layout for all the pages of your application:
app/views/
layouts/main.blade.php
page1.blade.php
layouts/main.blade.php:
<html>
<head>...</head>
<body>
<div>Your header that will be included in each of your pages</div>
<!-- The content of the current page: -->
#yield('body')
</body>
</html>
page1.blade.php:
#extends('layouts.main')
#section('body')
<div>The content of your page</div>
#stop
Learn more about the Blade templating engine.
Now where do you fetch your data?
The fastest/easiest way to develop is to use the routes as Controllers and as your application evolves you start refactoring your code and create Controllers.
app/routes.php:
Route::get('page1', function(){
//Fetch your data the way you prefer: SQL, Fluent or Eloquent (Laravel ORM)
//$data = DB::select('select * from yourtable');
$data = YourModel::all();
//Pass your data to the view
return View::make('page1')
->with('data', $data);
});
The data can be fetch using Fluent class or Eloquent ORM.
I suggest you to learn the basics of Laravel to properly create the base of your application so it will be really easy to maintain in the future.
The answer and issue here is not so simple. First have just been introduced to MVC and trying to understand the basic concept, the flow for MVC is Controller->Model->View. Here we see that the data is passed from the model directly to the View. The current examples of how to use Laravel MVC is to have the Model return data to controller making the flow as follows: Conntroller->Model-Controller->View. Here we see that the model and view are not aware of each other. A qucik look on wikipedia show that this type of modeling and controlling is know has MVA. The A is for adapter and also known as mediating controller, so now we are back to the answer here. Should we be using MVA or MVC? How would one achieve true MVC in Laravel? Answer is to use {{Form:model}} facade for true MVC. But then what happens if the view changes? should we be calling model from the view to get the new data? Answer is no, if the view has to change then user should have caused a controller to react kicking off a new cycle of MVC. So what we can see here a mix of MVC and MVA using the Laravel framework, can achieve a highly customized flow based on the needs of the site.