In Laravel, how would I handle the route if it was generated dynamically? What im trying to do is give the user the ability to create pages on a website so say they wanted to create /about but that isn't listed in the routes file because they would be adding this in through an admin panel. I am trying to figure out how will I make it so I can get the full URL, see if it is a page that already exists in the route file, if it doesn't then check the database to see if that name exists for a page and if it does show the content from that page.
To achieve dynamic routing, you could do something along the lines of:
Route::get('/{pageName}', function($pageName) {
// Do your logic here to determine if the page is in the database, or a file.
});
Take a look at the Laravel documentation on Routing Parameters to see what else you can do with them. In my opinion, the Laravel routing system is very clean and extremely powerful.
Update
One way of doing multiple routes would be like so:
Route::get('/{pageName}/{subPage}', function($pageName, $subPage) {
// Do your logic here to determine if the page is in the database, or a file.
});
You can get into far more advanced URL structures as well by utilizing regular expressions. It's all documented in the link provided above.
Related
So I am working on a project and I have decided to use php laravel framework, but when it comes to things like creating a new page and dealing with page redirects etc, am I right in thinking that all these will be handled in the route/web.php file so all the pages for my application will be defined in the route along with the view ?
I was thinking what if my application grows to have dozens of pages is it best practice to define each one on the route or are there better ways to handle this?
Yes, the best way to do routing is laravel to have each route for . each page, the only exception is when you have dynamic routes, for example, if you have a route that checks for users id or category for some product etc and it looks something like this Route::get("/product/{$category_id}","FrontController#methodForGetingProduct").
And later in Controller, you define what will you send and receive of the information and what view should be returned.
you can follow this type routing .......
Im not even sure if this is possible but what I am trying to do is this. I store different page modules in a database. When someone goes to a page with one of these modules, the pageController recognizes its a module and ( using the redirect path stored with this module in the DB ) redirects them to a get route which is how I know what info to pull and put on the page.
For instance, if someone was to go to /photo-album the pageController would recognize that was a page module and returns the redirect ( redirect/photo/albums ) and then redirects them to that route.
Route::get('redirect/photo/albums', ['uses' =>'PageController#getPhotoAlbums']);
The problem is the url then becomes /redirect/photo/albums. I would like it to maintain /photo-album
The reason I am doing it this way is because there will be several modules stored and each one will contain different things ( think blog, photo albums, video gallery etc. ). I need the redirect to figure out what goes on that page and what view to show. In this case PageController#getPhotoAlbums goes to the getPhotoAlbums method, pulls the photos and serves up the photoalbums view.
There may be a better way to do this and i'm open to it. Thanks in advance.
I don't have enough rep to comment, so I'll put this as an answer and hope it helps:
You really shouldn't get data from another controller. All your data should be available in the Eloquent model. This is important to the 'MVC' architecture.
There is more discussion on this here: Laravel: Load method in another controller without changing the url
So essentially, when your controller recognises it as a page module it should pull that data from the DB using Eloquent and then pass that to a View. That will mean that the original request URL is still retained.
I'm trying to build a simple PHP MVC framework. What I have right now is a basic set-up with a router that sends the request to the right controller, so I'm making the URL
/blog/[id]
Resolve to a class method like
Blog->singlePost();
Within singlePost(); I then interact with the model to get the right blog post and send it off to the view. The basic MVC triad is all there.
But pages are more complex than this. I've got a sidebar that I need to fill with data (from the database and other sources). I've got a main menu to build, I need to show the details for the current logged in user, and more. But, that said, I don't need all of these sections on every page.
My question is, where do I initiate/build all these various shared sections for the view?
My options that I can think of are:
Have every controller send a request for the required additional sections to be built (would have to update every controller each time something is added, no way)
When mapping the URL's, define a group that the route belongs to that loads in all the required sections (Not ideal, not every section will be needed on every page, could get messy)
Have the View (or Template) embed these sections on-demand. So the data for these sections would not be retrieved until the view explicitly asks for the data (The basic functionality of this seems quite appealing, but does it break the rules of what the view should do?)
Something else?
3 Seems quite appealing to me because I'd like for my templates (that will be dynamic and switchable via a template system) to be able to request a section on any page. So one template may show the "Top 10 Blog Posts" on the homepage, but another may not, so there's no point in loading it. I see that with Symfony/Twig, you can do this: http://symfony.com/doc/2.0/book/templating.html#embedding-controllers
Is this a good idea for various modules on a site? Or should everything be loaded before the view starts being processed?
I know this question has been asked in a similar fashion several times. However, I'm struggling to find any answers that would work in my situation. I primarily work on Microsoft projects and stepped in on this project to help during crunch.
Here's the situation.
We have a client who has a site with over 600 different pages. In reality each page uses the same template just populates with different data. We've developed a CMS for him which allows him to create new pages at will.
My ideal solution would allow me to store the name of a newly created page in a DB.
Ex. new_page_1 has been created and now exists in the DB. Now when I type in www.mysite.com/new_page_1 this needs to go to a controller that looks up "new_page_1" (in DB) and if it exists loads a view (THIS VIEW WILL NEED TO BE USED FOR ALL 600 pages) which then takes other data from the DB and populates various sections.
So essentially, over 600+ pages need to use the same route array and map to the same controller which then maps to the same view.
I've tried using $route['(:any)'] = 'custom_controler/create/$1 and as well as the same array key but using main and _remap. No matter what every single time it tries to look for the page name in my views (which it will never exist because I'm using one generic view for 600 pages)
Any ideas on how to accomplish this?
UPDATE
routes.php (this is the last line in the file)
$route['(:any)'] = "main/create/$1";
main.php (controller)
class Main extends MY_Controller {
public function __construct() {
parent::__construct();
}
public function create($page)
{
$c = new Category();
$c->get_by_name(ucfirst($page));
$this->load->view('site/index',$c);
}
}
the URL I'm attempting is sitename.servername.com/health sitename and servername obviously substituted.
The error I get is
An Error Was Encountered
Unable to load the requested file: health/main/create.php
Is the error page you're seeing the CodeIgniter error template or a generic server error? That error string sounds very much like you are using Apache or Nginx (or whatever main webserver you use) and its actually not even resolving to your CodeIgniter app at all, but searching for a PHP file that doesn't exist. You'll probably need to use mod_rewrite or something like that to make that URL point at the CodeIgniter install.
Otherwise, your implementation doesn't look completely wrong: you probably need to make sure main.php is the default route as well.
Your application will only look for the page name in your views if you tell it to. Your catch-all controller method should be checking the database for a valid page name, and then regardless of which pages validate, loads the same view (albeit with different data passed to the view).
Using an (:any) catch-all route is perfectly fine. Your controller code somewhere is what's throwing you off. Update your post with the code if you continue to struggle.
I’m a recent user of Codeigniter and am developing a simple backend CMS to manage pages.
Based on a URL (in this example I have hidden “index.php”) : mysite.com/pagename
I would like the system to detect if there is a value of “pagename” in my database, if there is, I need the system to re-route to a custom controller (eg: Pagemaker) and if there is no record called pagename, just do it’s normal thing (i.e. find a controller called pagename)
Currently I have:
$route['(:any)'] = "pagemaker/create/$1";
whereby all requests are forwarded to my custom function.
However I want to change this structure so that if the page does NOT exist in the db, the traditional codeigniter request process is followed.
Can anyone offer any advice about how to complete this? Or any advice about routing custom CMS’s in codeigniter in general?
The best solution is to upgrade to CI 2.0 because it's stable enough and it gives you plenty of useful features.
In your case, set the following route:
$route['404_override'] = 'pagemaker';
If the router doesn't know where to go it just goes to pagemaker controller. This can then check if the first uri segment exists and if not you create a custom 404 page instead of the crappy default one.
And I don't want to hear any of this "Oh but it's not released yet" crap, I've been using it CI 2.0 for almost a year. ;-)
I can think of two possibilities:
1) Edit your custom function to let it redirect your client when page's not in the db
pseudo code:
if($dbresult == null){
redirect("http://yoursite.com/"+$this->uri->segment(3));
}
2) Edit the router class of CI so it will first check if the page's in the db and if not, just continues. This may be somewhat messier as you need a db connection in your Router.php