I have the following structure:
index.php
/app
/images
I have routes setup for all the different pages and whatnot but when I try to access an image directly it tries to pick that route up as one of my dynamic routes.
So for context, I am converting this from a pre-existing app and to maintain the links/paths that it had, I have a completely dynamic route at the end of the index:
$app->get('/{page}', 'HomeController:processRequest');
$app->get('/{page}/{id}', 'ProductController:viewProduct');
$app->get('/{page}/{id}/{show}', 'ProductController:viewProduct');
So when I do the following in an image tag:
https://example.com/images/nav/tinycheck.png
That route kicks in and it fails. Is there any way to tell Slim to ignore anything with 'images' in the path and just serve up the image?
I have tried looking at a bunch of other threads on here but nothing is pointing me to the answer.
I seem to have resolved it with the following:
$app->get('/images/nav/{data}', function($request, $response, $args) {
$data = $args['data'];
$image = #file_get_contents("/mypath/images/nav/".$data);
if($image === FALSE) {
$handler = $this->notFoundHandler;
return $handler($request, $response);
}
$response->write($image);
return $response->withHeader('Content-Type', FILEINFO_MIME_TYPE);
});
Related
I am following a tutorial to learn Laravel 8. I've created a simple view that contains 3 articles. Each article has a link to another html page. The exercise is to create URLs in web.php.ur
I have 2 views post.blade.php and posts.blade.php(the main one) , the other articles in html are contained in a posts folder in ressources.
Route::get('posts/{post}', function ($view) {
$post = file_get_contents(__DIR__ . "/../ressources/posts/{$view}.html");
return view('post', [
'post' => $post,
]);
});
This is the url: http://127.0.0.1:8000/posts/my-first-post
This the error I get:
file_get_contents(C:\xampp\htdocs\laravel2\laravel2\routes/../ressources/posts/my-first-post.html): Failed to open stream: No such file or directory
I don't understand what went wrong since I'm copying exactly what the tutorial is doing.
Start from here https://laracasts.com/series/laravel-8-from-scratch
You will have each nuts and bolts of laravel clear. This series is very precise to get you started in laravel.
In routes/web.php page
Route::get('/posts', [PostController::class, 'index']);
And in View page
Posts
First, i want to say that if your instructor really told you to write this
file_get_contents(__DIR__ . "/../ressources/posts/{$view}.html") , then he doesn't know anything about laravel and the MVC structure. stop following that.
This is the solution based on what i understood from your example:
so there is a html file named 'my-first-post.html' in your 'ressources/posts' directory. Rename it to 'my-first-post.blade.php'
in the post.blade.php file, just include that file using #include('posts.' . $post)
and change the controller to this:
Route::get('posts/{post}', function ($post) {
return view('post', [
'post' => $post,
]);
});
I'm trying to navigate to a page I created for the logged in profile of a doctor. I have not put in any authentication as I want to take care of the front end first then move to that part of the project. So basically I wanted to navigate to those pages with just putting in the url in the browser but that's not working. I'm new to laravel and am working on a project that was a template first so I'm having a bit of trouble finding things and putting in the correct paths.
I've tried putting the path in the web.php and my PagesController in a few different ways but nothing has worked so far.
my web.php :-
Route::get('/login.profile', 'Frontend\PageController#loginProfile');
my PagesController :-
public function loginProfile(){
$data['page_title'] = 'Profile';
return view('frontend/login.profile');
}
the path to the file :-
\Desktop\doctor\resources\views\frontend\login\profile.blade.php
Try to define the route like this:
Route::get('/login/profile', 'Frontend\PageController#loginProfile'); // I removed the dot from the url
and the controller method like this:
public function loginProfile(){
$data['page_title'] = 'Profile';
return view('frontend.login.profile', $data);
// also view('frontend.login.profile')->withData($data)
// and view('frontend.login.profile')->with(['data' => $data]) should work
// You will have a $data array available in the template
}
the path to the controller should be app/Http/Controllers/Frontend/PageController.php and the path to the view should be resources/views/frontend/login/profile.php.
When pointing to files, many Laravel method replace dots with slashes. That's a feature that's there to allow you to navigate/access stuff in a more "object-oriented" style, i would say. Let me know if it works.
I'm starting a new project using Slim framework. So far it's going decently, everything I'm looking for in a micro framework. I have been away from the PHP world for a while so I am now getting to know the built in PHP web server. The only issue is this: How do I serve my static content?
For reference, here is my project layout:
project:
public folder
index.php
static/css/style.css
templates/index.html . # I'm using twig (coming from python Flask)
My template:
<html>
<link href="{{ base_url() }}/css/agency.css" rel="stylesheet">
<!-- other cool layout stuff -->
and my index.php (very minimal)
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->get('/', function ($request, $response, $args) {
$response = $this->view->render($response, 'base.html');
return $response->write("Hello ");
});
$app->run();
When I start the built in php server from the command line, I do this:
php -S localhost:8080 -t public public/index.php
While this works great, when I try to access my static content, it just returns the rendered base.html file
Please let me know the best way to start this so static content is rendered correctly. Your help is appreciated.
So based on the documentation as pointed out by kuh-chan and Nima, I expanded it for both Slim purposes, as well as returning a 404 response if the file did not exist.
if (PHP_SAPI == 'cli-server') {
$url = parse_url($_SERVER['REQUEST_URI']);
$file = __DIR__ . $url['path'];
// check the file types, only serve standard files
if (preg_match('/\.(?:png|js|jpg|jpeg|gif|css)$/', $file)) {
// does the file exist? If so, return it
if (is_file($file))
return false;
// file does not exist. return a 404
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
printf('"%s" does not exist', $_SERVER['REQUEST_URI']);
return false;
}
}
I'm brand new to Laravel, and I'm tinkering with it in different ways to understand how it works.
One of the first things that I've tried is to create routes dynamically by creating a routes config file that is essentially an array of views, and loop through them to create the route. It looks like this:
// Loop through the routes
foreach( config("routes.web") as $route ){
$GLOBALS["tmp_route"] = $route;
// set the path for home
$path = ($route == "home" ? '/' : $route);
Route::get( $path, function() {
return view($GLOBALS["tmp_route"]);
});
// foreach
}
I know the loop is working fine, but what I get is 'Undefined index: tmp_route'.
I'm confused as to why this isn't working? Any ideas? If I echo out the tmp_route it echos out the value, but fails at the return view(.
We don't use loops in routes usually. Actually, I've never used a loop in routes if I remember correctly. My suggestion is create a route with paramater and assign it to a controller method. e.g:
// Note that if you want a route like this, just with one parameter,
// put it to end of your other routes, otherwise it can catch other
// single hard-coded routes like Route::get('contact')
Route::get('{slug}')->uses('PageController#show')->name('pages.show');
Then in your PageController
public function show($slug) {
$view = $slug == '/'?'home':$slug;
return view($view);
}
With this, http://example.com/my-page will render views/my-page.blade.php view. As you can see I also gave him a name, pages.show. You can use route helper to create links with this helper. e.g.
echo route('pages.show','about-us'); // http://example.com/about-us
echo route('pages.show','contact'); // http://example.com/contact
In blade templates:
About Us
Please look at the documentation for more and other cool stuff
There will be several high profile links for customers to focus on, for example:
Contact Us # domain.com/home/contact
About the Service # domain.com/home/service
Pricing # domain.com/home/pricing
How It Works # domain.com/home/how_it_works
Stuff like that. I would like to hide the home controller from the URL so the customer only sees /contact/, not /home/contact/. Same with /pricing/ not /home/pricing/
I know I can setup a controller or a route for each special page, but they will look the same except for content I want to pull from the database, and I would rather keep my code DRY.
I setup the following routes:
Route::get('/about_us', 'home#about_us');
Route::get('/featured_locations', 'home#featured_locations');
Which work well, but I am afraid of SEO trouble if I have duplicate content on the link with the controller in the URL. ( I don't plan on using both, but I have been known to do dumber things.)
So then made routes like these:
Route::get('/about_us', 'home#about_us');
Route::get('/home/about_us', function()
{
return Redirect::to('/about_us', 301);
});
Route::get('/featured_locations', 'home#featured_locations');
Route::get('/home/featured_locations', function()
{
return Redirect::to('/featured_locations', 301);
});
And now I have a redirect. It feels dumb, but it appears to be working the way I want. If I load the page at my shorter URL, it loads my content. If I try to visit the longer URL I get redirected.
It is only for about 8 or 9 special links, so I can easily manage the routes, but I feel there must be a smart way to do it.
Is this even an PHP problem, or is this an .htaccess / web.config problem?
What hell have I created with this redirection scheme. How do smart people do it? I have been searching for two hours but I cannot find a term to describe what I am doing.
Is there something built into laravel 4 that handles this?
UPDATE:
Here is my attempt to implement one of the answers. This is NOT working and I don't know what I am doing wrong.
application/routes.php
Route::controller('home');
Route::controller('Home_Controller', '/');
(you can see the edit history if you really want to look at some broken code)
And now domain.com/AboutYou and domain.com/aboutUs are returning 404. But the domain.com/home/AboutYou and domain.com/home/aboutUs are still returning as they should.
FINAL EDIT
I copied an idea from the PongoCMS routes.php (which is based on Laravel 3) and I see they used filters to get any URI segment and try to create a CMS page.
See my answer below using route filters. This new way doesn't require that I register every special route (good) but does give up redirects to the canonical (bad)
Put this in routes.php:
Route::controller('HomeController', '/');
This is telling you HomeController to route to the root of the website. Then, from your HomeController you can access any of the functions from there. Just make sure you prefix it with the correct verb. And keep in mind that laravel follows PSR-0 and PSR-1 standards, so methods are camelCased. So you'll have something like:
domain.com/aboutUs
In the HomeController:
<?php
class HomeController extends BaseController
{
public function getAboutUs()
{
return View::make('home.aboutus');
}
}
I used routes.php and filters to do it. I copied the idea from the nice looking PongoCMS
https://github.com/redbaron76/PongoCMS-Laravel-cms-bundle/blob/master/routes.php
application/routes.php
// automatically route all the items in the home controller
Route::controller('home');
// this is my last route, so it is a catch all. filter it
Route::get('(.*)', array('as' => 'layouts.locations', 'before' => 'checkWithHome', function() {}));
Route::filter('checkWithHome', function()
{
// if the view isn't a route already, then see if it is a view on the
// home controller. If not, then 404
$response = Controller::call('home#' . URI::segment(1));
if ( ! $response )
{
//didn't find it
return Response::error('404');
}
else
{
return $response;
}
});
They main problem I see is that the filter basically loads all the successful pages twice. I didn't see a method in the documentation that would detect if a page exists. I could probably write a library to do it.
Of course, with this final version, if I did find something I can just dump it on the page and stop processing the route. This way I only load all the resources once.
applicaiton/controllers/home.php
public function get_aboutUs()
{
$this->view_data['page_title'] = 'About Us';
$this->view_data['page_content'] = 'About Us';
$this->layout->nest('content', 'home.simplepage', $this->view_data);
}
public function get_featured_locations()
{
$this->view_data['page_title'] = 'Featured Locations';
$this->view_data['page_content'] = 'Featured properties shown here in a pretty row';
$this->layout->nest('content', 'home.simplepage', $this->view_data);
}
public function get_AboutYou()
{
//works when I return a view as use a layout
return View::make('home.index');
}