• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Playing with Routes. How can i control it?

HDJuegos

Active member
#1
Hi, i'm working now in my own news system for my site and i'm very interested in create my own http route, but i dont know very well how to use multiple prefix.

For example, i know i can create my own prefix from developer admin and also add news prefixes using the model ActionPrefix() in ControllerPublic. But i had two questions about (forget about create a category, i only want help code in routes):

Imagine "news" is my Add-on and i had it working in developer mode, with prefix added.

1. How can i create a route prefix for this?:

www.mysite.com/news/sports/spain-wins-world-cup < a new about a sport
www.mysite.com/news/cars/new-ferrari-in-2001 < a new about a car

2. I want also to do a reroute like this:

if i write this:

www.mysite.com/all-about/cars

without redirect, XenForo returned the same output as:

www.mysite.com/news/cars/

( Yes, people look at URL and see http://www.mysite.com/all-about/cars and XenForo returns the same as www.mysite/news/cars )

My goal is learn to play with all type of routes.

Thanks in advance and sorry if my english isn't good.
 

Arik

Well-known member
#3
Sorry, not completely understanding the language you're using in your second paragraph.

I haven't spent a ton of time looking at route prefixes, so I can't give you a definitive answer, but here's where I'd start to get these URLs:

1. I'd create a news prefix, then within MyAddon_Route_Prefix_News::match() I'd assign the last two parameters within code (check out XenForo_Router::resolveActionWithStringParam() for a starter).

2. First thing I'd try is creating a new RoutePrefix within the admin and pointing /all-about/ to the same RoutePrefix class as /news/

Again, I haven't tried it. This is just where I'd start.
 

HDJuegos

Active member
#4
I'm looking at the code.

So i can use resolveActionWithStringParam() to get "sports/spain-wins-world-cup" (using explode with "/") ??
 

Arik

Well-known member
#7
I'm looking at the code.

So i can use resolveActionWithStringParam() to get "sports/spain-wins-world-cup" (using explode with "/") ??
The resolveActionWithStringParam method only allows for one single parameter within the URL. You'd have to write your own to pull out the various variables within the URL. You could go down two roads for this (as I'm thinking about it).

  1. You could have it explode out the path, and pick the sections in these two spots (I think they'd be 0 & 1, not sure what the $routePath contains off the top of my head). This would allow you to easily specify an action with the URL if you wanted to use more than the Index action.
  2. You could explode out the path, and accept an arbitrary number of arguments. This would make it more flexible (as you could then do categories/subcategories), but you wouldn't necessarily know if the URL contained an action, or just category/subcategory/title. Easiest way around this would be to pass an array to this method that contains the available actions for your Controller class...again if you wanted more than just the Index action. This presents the inevitability of redundant data between the Controller and the Route Prefix.
You'd also likely have to work out how to have it output the URLs, too, since this doesn't appear to be something the router was set up to do.

Again, I haven't fully thought this through. It's not something I've been interested in exploring, so there may be a more elegant solution. But, given the methods I have seen, and the fact that XenForo only seems to go one level deep (notice no forum information within the URL on this page), I'd doubt that it's built in.
 

Shadab

Well-known member
#10
I'm playing with symfony's routing system and trying to integrate it with xenforo, for handling multiple "sub routes" within a static route prefix. So far so good. Here's some sample code which adds 3 sub-rules for route prefix "test":

PHP:
class GeekPoint_CustomRouting_RoutePrefixTest extends GeekPoint_CustomRouting_Abstract
{
	protected function _initialize()
	{
		$controller = 'GeekPoint_CustomRouting_ControllerTest';

		$this->addSubRule('main', '',
			array('controller' => $controller, 'action' => 'index')
		);

		$this->addSubRule('section', ':section/:page',
			array('controller' => $controller, 'action' => 'foo', 'page' => '1'),
			array('page' => '\d+')
		);

		$this->addSubRule('article', ':section/:slug',
			array('controller' => $controller, 'action' => 'bar'),
			array('slug' => '[a-z\-]+')
		);
	}
}

» ./test/
Code:
Request Parameters array(0) {
}
Method Called string(11) "actionIndex"

» ./test/sample-section/
Code:
Request Parameters array(2) {
  ["page"] => string(1) "1"
  ["section"] => string(14) "sample-section"
}
Method Called string(9) "actionFoo"

» ./test/sample-section/1608/
Code:
Request Parameters array(2) {
  ["page"] => string(4) "1608"
  ["section"] => string(14) "sample-section"
}
Method Called string(9) "actionFoo"

» ./test/sample-section/my-article-title/
Code:
Request Parameters array(2) {
  ["section"] => string(14) "sample-section"
  ["slug"] => string(16) "my-article-title"
}
Method Called string(9) "actionBar"

I haven't benchmarked this approach yet; but it would definitely have a performance hit if the sub-rules are not cached aggressively across multiple requests.
 

Jaxel

Well-known member
#11
Why dont you just do what I did for my mods? Handle sublinks with underscores? In your code, you can construct a string which has the subdirectories, with each slash replaced with an underscore...
Code:
<?php

class EWRmedio_Route_Category implements XenForo_Route_Interface
{
public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
{
return $router->getRouteMatch('EWRmedio_ControllerPublic_Media', 'index', 'media_category', $routePath);
}

public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
{
$outputPrefix = str_replace('_', '/', $outputPrefix);
return XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix, $action, $extension, $data, 'category_id', 'category_name');
}
}
Then when you're building the public links, simply use str_replace to parse out the slashes...



Lets say you construct $section with: "_category_section"
Code:
{xen:link 'full:test{$section}', $article}
This will construct a link to /test/category/section/article_slug

Then you could even go further and then add extensions to the link:
Code:
{xen:link 'full:test{$section}/edit', $article}
This will construct a link to /test/category/section/article_slug/edit

Then in your controller, split your MinorSection:
Code:
$slugs = explode('/', $this->_routeMatch->getMinorSection());
Of course, then you need to use end($slug) to get the last element of the exploded array. Use a simple switch to differentiate the possible values... if it equals "edit", send it to the appropriate action... otherwise default to the viewing action with the article name as the slug. The downside of this, is you can't have an article named "edit".
 
F

Floris

Guest
#12
Holy batman, this is almost over my head, but I can still follow it .. Great resource to read and learn from. Thanks for taking the time to discuss this. I am trying stuff out now and this thread actually helped me figure a few things out - saved me from having to start a thread, explain it all and hoping someone had a reply :D thumbsup