I have an asp.net mvc3 website. It replaced an older php website. Many people have parts of the site bookmarked in reference to the .php locations and I would like to add those back into the asp.net site as simple forwards to the new location. So mysite/product.php would redirect to mysite/usermap/product.cshtml for example. When I insert the product.php into the directory and use an anchor href to it, I am prompted to open it with a certain program or save it. Any ideas?
You could make a small redirection controller, and add a route to match something like mysite/{id}.php.
Then in that controller
public ActionResult Index(string id)
{
return RedirectToActionPermanent("Product", "YourExistingController", id);
}
edit
In your global.asax.cs file
public void RegisterRoutes(RouteCollection routes)
{
// you likely already have this line
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// assuming you have a route like this for your existing controllers.
// I prefixed this route with "mysite/usermap" because you use that in your example in the question
routes.MapRoute(
"Default",
"mysite/usermap/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// route to match old urls
routes.MapRoute(
"OldUrls",
"mysite/{oldpath}.php",
new { Controller = "OldPathRedirection", action = "PerformRedirection", oldpath = "" }
);
}
Then you would define an OldPathRedirectionController (Controllers/OldPathRedirectionController.cs most likely)
public class OldPathRedirectionController : Controller
{
// probably shouldn't just have this hard coded here for production use.
// maps product.php -> ProductController, someotherfile.php -> HomeController.
private Dictionary<string, string> controllerMap = new Dictionary<string, string>()
{
{ "product", "Product" },
{ "someotherfile", "Home" }
};
// This will just call the Index action on the found controller.
public ActionResult PerformRedirection(string oldpath)
{
if (!string.IsNullOrEmpty(oldpath) && controllerMap.ContainsKey(oldpath))
{
return RedirectToActionPermanent("Index", controllerMap[oldpath]);
}
else
{
// this is an error state. oldpath wasn't in our map of old php files to new controllers
return HttpNotFoundResult();
}
}
}
I cleaned that up a little from the original recommendation. That hopefully should be enough to get you started! Obvious changes are to not hardcode the map of php filenames to mvc controllers, and perhaps altering the route to allow extra params if you require that.
If you are using IIS7 the Url rewrite module is great. Here is the page: http://www.iis.net/download/urlrewrite
When I insert the product.php into the directory and use an anchor href to it, I am prompted to open it with a certain program or save it. Any ideas?
Update the handler mappings manually. However I am pretty sure when you install PHP for IIS (http://php.iis.net/) it will do it for you.
Install PHP into IIS using this site. http://php.iis.net/
Related
i want to achieve url routing something like www.example.com/alicia
suppose alicia is not a class name or method name just something like passing data in url and with some class i want to access this and want to use it for further process.How i can use it ? Thanks in advance.
You can use Codeigniter's built-in routing, the file route.php is located in your config folder.
there you can add:
$route['alicia'] = 'welcome/index/something';
$route['alicia/:any'] = 'welcome/index/someotherthing/$1';
then in your controller, for example welcome you just create a function like:
public function index($page = null){
if($page=='something'){
// do what you need to do, for example load a view:
$this->load->view('allaboutalicia');
}
elseif ($page=='someotherthing'){
// here you can read in data from url (www.example.com/alicia/2017
$year=$this->uri->segment(2); // you need to load the helper url previously
}else{
// do some other stuff
}
}
documentation on routing and on urlhelper
edit after comment:
in case your uri segment is representing a variable, like a username, then you should use a uri scheme like www.example.com/user/alice and create your route like:
$route['user/:any'] = 'welcome/index/user';
then in your controller welcome
public function index($page=null){
if($page=='user'){
// do what you need to do with that user
$user=$this->uri->segment(2); // you need to load the helper url
}
else{
// exception
}
}
This could be tricky because you don't want to break any existing urls that already work.
If you are using Apache, you can set up a mod_rewrite rule that takes care to exclude each of your controllers that is NOT some name.
Alternatively, you could create a remap method in your base controller.
class Welcome extends CI_Controller
{
public function _remap($method)
{
echo "request for $method being handled by " . __METHOD__;
}
}
You could write logic in that method to examine the requested $method or perhaps look at $_SERVER["REQUEST_URI"] to decide what you want to do. This can be a bit tricky to sort out but is probably a good way to get started.
Another possibility, if you can think of some way to distinguish these urls from your other urls, would be to use the routing functionality of codeigniter and define a pattern matching rule in the routes.php file that points these names to some controller which handles them.
I believe that the default_controller will be a factor in this. Any controller/method situations that actually correspond to a controller::method class should be handled by that controller::method. Any that do not match will, I believe, be assigned to your default_controller:
$route['default_controller'] = 'welcome';
Im trying to get the layered navigation of a category links from a php that is outside magento.
I can create all of the category html, but the problem is that the layered links are created with the params of frontcontroller (at the same way of the toolbar links).
If i have a filter selected the creation of layered links doesnt take account of it, and also the layered links havent the category url...
I try to recreate the frontcontroller of the category page inside magento on my php ouside that, but i haven success... Even i recreate the $_SERVER, but the controller seems to not find a router...
In the php if i use mage::run, it do the operation of calcule correctly but mage::run makes the response and isnt i want because i need an xml output only of layered navigation.
If i use mage::app i can get the category html, but the controler isnt calculated correctly although is the same $_SERVER[request_uri] and havent correct links. The front controller havent action...
In the frontcontroller request i see two differences: in magento dispathed is true, but in the php no, and in magento de request_uri are rewrited to catalog/category/view/id/7?color=99 while in the php not hombre.html?color=99
Im missing anything, i need to initialize the front controller? o reinitialize???
Or there a different way to get the layered navigation from outside magento??
I found the problem and the solution...
On start magento it calls to rewrite the URL with the aim to get converted friendly url on a route url...
hombre.html?color=99 is converted on catalog/category/view/id/7?color=99
So the first is to call Mage::getModel('core/url_rewrite')->rewrite(); and now our frontcontroller request have the URL converted correctly.
Before that the frontendcontroller is inited executing the function match in all of its routers to try to find a controller and an action...
$frCont = Mage::app()->getFrontController();
foreach ($frCont->getRouters() as $router) {
if ($router->match($frCont->getRequest())) {
break;
}
}
With that two steps i have the frontcontroller initialized like if i access to the url "hombre.html?color=99" but in fact im on another php in my services folder.
But the match function after initialize the frontcontroller and get the router, action, and route, dispatch the action by default, so it generate all the html output and cannot work with layouts... So i create a local copy of the class Mage_Core_Controller_Varien_Router_Standard and i have updated the function match:
public function match(Zend_Controller_Request_Http $request){
.
.
.
$controllerInstance->dispatch($action);
return true;
}
for this one
public function match(Zend_Controller_Request_Http $request, $dispatchAction = true){
.
.
.
if($dispatchAction==true){
$controllerInstance->dispatch($action);
}
return true;
}
So in my service php i have that code:
Mage::getModel('core/url_rewrite')->rewrite();
$frCont = Mage::app()->getFrontController();
foreach ($frCont->getRouters() as $router) {
if ($router->match($frCont->getRequest(),false)) {
break;
}
}
And i have the frontcontroller initialized and the action,router,params, etc assigned like if i access from the catalog URL but withouth dispatching the action, and then i can write the objects i want with the layout object.
Hope it helps anyone.
I have set up friendly URLs for a few search result pages, using a custom route for each:
friendly_search_resultpage:
url: /products/my-friendly-alias
param:
module: products
action: search
querystring: searchattribute
querystring2: searchattribute2
This works fine, but when doing the search directly (i.e. browsing to /products/search?querystring=search...) I want to set a <link rel="canonical"> containing the matching friendly URL. This will help Google understand the relation and that there isn't duplicate content.
I put my friendly URL route at the top of routes.yml and hoped for a magic match, but URL parameters aren't recognised in the checking done by symfony. I have dug into sfRoute, with no luck. Is it possible?
I ended up writing a custom routing class to use for these routes, which is executed when url_for() is called. Here is the code:
<?php
class mySearchFriendlyRoute extends sfRoute
{
public function matchesParameters($params, $context = array())
{
// I can't find symfony sorting parameters into order, so I do
// (so that foo=x&bar=y is treated the same as bar=y&foo=x)
ksort($params);
$mine = $this->defaults;
ksort($mine);
if ($params == $mine) {
return true;
}
return false;
}
}
To use, add class: mySearchFriendlyRoute to the routes.yml entry.
Try to use Your own Route:
friendly_search_resultpage:
class: YourRouteClassName
...
And overload sfRoute::generate() there by concrete cannonicalization (return the canonical URL).
This redirects with 301 in my project upon of last sf1.4 revision.
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');
}
I am new to Silverstripe Framework / CMS. I see ./mysite/code/Page.php as controller and ./themes/simple/... as template directory. I logged into the admin panel and added new test page. The menu appears on the website with the URL http://example.com/test and content is displayed.
So what I want to know is, how to access the new controller let say Download.ss. I want to access the URL http://example.com/download/123/ without adding the new page download in admin panel. Thank you.
First of all, any files with a .ss extension are template files not controllers.
Create a new class in mysite/code/Download.php which extends Controller.
class Download extends Controller {
public function index() {
// Automatically handles URLs like http://example.com/Download
}
public function exampleaction() {
// Automatically handles URLs like http://example.com/Download/exampleaction
}
}
After that you'll want to add a new routes.yml file to the mysite/_config directory to specify that the index function on your new controller should handle calls to http://example.com/download/123.
---
Name: downloadrules
---
Director:
rules:
'download/$ID': Download
Now the '123' portion of your example URL will be accessible as $this->request->param('ID') within the index function.
Now you can do:
class Download extends Controller {
public function index() {
$fileID = $this->request->param('ID');
// Do your thing.
}
}
Documentation for this stuff is at http://doc.silverstripe.org/framework/en/reference/director