Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC:

SEF and components 06 Oct 2015 12:46 #13571

  • MorganL
  • MorganL's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
How can I control the SEF for a J-Cook created component?

I have a table called deals, with individually named items.

When I create a menu pointing at the collection view its fine
http://(domain)/deals

However when I click on a deal it returns
http://(domain)/deals/deal/deal?cid[0]=1

Ideally I would prefer
http://(domain)/deals/($this->item->dealname) i.e http://(domain)/deals/free-beer-2015

Or at a push
http://(domain)/deals/deal/free-beer-2015

Anyone know how to get me started on the implementation of this so I can at least improve on the default?
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla

Please Log in or Create an account to join the conversation.

SEF and components 06 Oct 2015 15:42 #13572

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 986
I am not expert in that, but I can give you a hint.

Edit router.php of your component. It contains the function to encode and decode the url params.
That's all I can say.
I always use the SEO of the menu system, and if it uses some filters, then they appears in clear. I never went so far in that.

Anybody can help ?
Coding is now a piece of cake

Please Log in or Create an account to join the conversation.

SEF and components 06 Oct 2015 16:16 #13573

  • MorganL
  • MorganL's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
Looks like I will be doing some reading later!

docs.joomla.org/Supporting_SEF_URLs_in_your_component
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla

Please Log in or Create an account to join the conversation.

SEF and components 06 Oct 2015 19:47 #13576

First:
You will have to change router.php in your component's root.
You can not fork it.

Second:
You need to change YourcomponentBuildRoute and YourcomponentParseRoute
Let's start with YourcomponentBuildRoute.

Is starts with setting $segments = array();
That will be your array of segments (duh).
Check the function and it will be quite clear:
This code
	if(isset($query['view']))
	{
		$view = $query['view'];
		$segments[] = $view;
		unset( $query['view'] );
	}
check for the query view (you will see this when you have SEF turned off.
Your url will be something like:
http://(domain/)index.php?option=com_yourcomponent&view=deals&Itemid=117
==> Itemdid is the id of the active menu, the view is in this case "deals"
segments[] will only return "deals".

No, when selecting an item, your url will probably be someting like:
http://(domain/)index.php?option=com_yourcomponent&view=deal&layout=deal&cid[0]=1&Itemid=117

Rewriting this will become:
http://(domain)/deals/deal/deal?cid[0]=1 The first "deals" in the URL you pasted is because your menuitem is called "deals".
Breaking down you have for the menuitem http://(domain)/deals/
Then the view = deal, and after that layout = deal
So, there is only cid[0]=1 left to route.

If your deal has a name, you can do this by checking $query after the check for view and layout
	if (isset($query['cid'])) {
        $db = JFactory::getDbo();
        $dbQuery = $db->getQuery(true)
            ->select('name')
            ->from('#__yourcomponent_deals')
            ->where('id=' . (int) $query['cid'][0]);
        $db->setQuery($dbQuery);
        $name = $db->loadResult();
//some url thingy, you can change it or make it safer/better
		$segments[] = urlencode($name);
		unset( $query['cid'] );
	}
The, your url will be on the list:
http://(domain)/deals/deal/deal/free-beer-2015

Without the YourcomponentParseRoute, this will not work because YourcomponentParseRoute has no way of knowing what "free-beer-2015" has for id to look for in the database. Cook needs cid[].

Let's make it understand:
Go to the url http://(domain)/deals/deal/deal/free-beer-2015, it will probably give a nice page without your item
Lookup to the YourcomponentParseRoute function and do a var_dump of the segments:
var_dump($segments);
Then refresh and on top of the page you'll see: array(3) { [0]=> string(6) "deal" [1]=> string(10) "deal" [2]=> string(7) "free-beer-2015" }
The first entry is your view, the second the layout, the router.php has code for that in the YourcomponentParseRoute function

The third part is the one we need, is it the name of our item.
So, after the first to segment-checks do a check on the 3rd:
	if (isset($segments[$nextPos])) {
        $db = JFactory::getDbo();
        //get the id from name
        $dbQuery = $db->getQuery(true)
            ->select('id')
            ->from('#__yourcomponent_deals')
            ->where("name='" . $segments[$nextPos]."'");
        $db->setQuery($dbQuery);
        $id = $db->loadResult();
        //set the var needed by Cook
        $vars['cid'][0] = $id;
        //move to next segment
	$nextPos++;
	}

That is basically it.
You will probably need to do some rework so that the name will always get the correct id, maybe work add an alias wizard to your table and work with that.
That is safer. For items with the same name you will have no problem then.
You can also use the id as an extra segment:
http://(domain)/deals/deal/deal/1/free-beer-2015

Good luck!
The following user(s) said Thank You: admin, MorganL

Please Log in or Create an account to join the conversation.

SEF and components 06 Oct 2015 22:59 #13577

  • MorganL
  • MorganL's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Posts: 438
  • Thank you received: 53
Brilliant explanation, look,forward to testing that tomorrow!
Morgan Leecy MCSE

Novell / Linux
PHP. MYSQL, Apache, node.js
Coldfusion, JQuery, HTML5
Joomla

Please Log in or Create an account to join the conversation.

SEF and components 07 Oct 2015 07:42 #13578

You can also check the router.php in com_content, is had also some DB lookups, might be a good example

I did some tinkering last night, but alias is not a good idea.
I came across the following when I added an alias field to my table
- Alias was not unique, the alias of a item called "Document 1" became document-1 but when creating another "Document 1", that also got the document-1 for alias.
- When trying alias as segment, I got for some reason document:1 and not document-1, therefore the item could not be found in de DB.

I ended up using the id and using the title for seo purposed:
http://domain/records/record/20/document-1.html
The other document 1 got:
http://domain/records/record/22/document-1.html

Regards.
The following user(s) said Thank You: admin

Please Log in or Create an account to join the conversation.

SEF and components 07 Oct 2015 11:27 #13582

  • admin
  • admin's Avatar
  • Offline
  • Administrator
  • Administrator
  • Chef
  • Posts: 3711
  • Thank you received: 986
Yes you are right, the mistake of Cook is to use cid[] in the url (inherited from old school way)
In the next release, this is deprecated. replaced by 'id'.
Coding is now a piece of cake

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
Time to create page: 0.070 seconds
  I still don't believe he can really be human to do all this ! From all of the forums that I've ever participated in this is certainly the one that most encapsulates the feeling of being truly open source where everyone's opinions and contributions can and will shape the development of the service! It's truly awesome! Hope you enjoy cooking and look forward to reading and contributing to any of the editorial work that you proposed too!! Thanks
Gez (audibleid - JED)

Get Started