Subcategories and resource controllers? - php

Im using a resource controller to control articles.
/news
Hits the index method and brings up all the articles under the category.
/news/article-slug
Hits the show method and brings up an article under the category.
My question involves sub categories.
/news/sub-category-name
This would hit the show method which would look for an article with the sub-category-name when I want it to hit the index method and bring up a list of articles for the sub category.
What would be the approach to use for sub categories?
Add another route and method like:
get('/news/{subcategory}', [
'as'=>'subcategory',
'uses'=>'ArticleController#getSubCategory',
]);
Or would it be better practice to scrap sub categories and have a url like:
/news-sub-category-name/article-slug
Or is there another way?

Thinking semantics you would be better to servers category names then the title. ie
www.domain.com/news/category/article
This will also give you a clean approach for your routes file. IE no wildcard matching or regex to replace (cat-) etc.
Thats the way I would personally go.
It use to be in the past you would want to keep your URL's as short as possible but thats just not the case these days. Dont get me wrong thats not to say you want domain/cat/cat/cat.....
... Update
To use resources you would have something like.
Route::resource('news/{cat}/article', 'ArticleController');

Related

How to Pass slugged url to Controller in Laravel

Hey Guys I am new to Laravel and I am currently trying to pass a slugged url into my controller, but I am having issues with it.
I have a table for categories and I have all the categories looped through and displayed on a view page (/posts). I listed all the categories on this view, so that when a user clicks on a category, they will be taken to a different page showing all posts belonging to that category(e.g, /posts/category/{categoryID}). I know I can get this done by passing the category id to the controller and finding the id to pass back to that view. However, I am trying to do something different.
I am looking to pass the category name instead of the id to the controller. E.g, /posts/category/{category name}. But due to the fact that some categories are more than a word (e.g, Dry Cleaning), it has become a challenge for me. I had earlier slugged the URL for SEO purpose (e.g, /posts/category/{Str::str(categoryname)}) and from the web.php file, I created a get route.
Now, I'd like to fetch all posts relating to the category name passed in. The issue is that the category names are slugged.
Is there a way to remove the slug("-" or hyphen) from the name passed into the controller? So, instead of "Dry-cleaning", it will come back as "Dry cleaning" which matches the name in the database.
I am trying to avoid passing id to the url.
Thanks.
Good question.
There are a couple of approaches you can use to tackle this problem. I'll run through them for you.
1. Store the slug in the database
One option is to store the slug name within the database. Personally this is my favourite option as you don't need to do any string transformations. With this approach I would put a slug column in your categories table. Then you can use the Category eloquent model to search for a category with that slug.
2. Convert the slug to title case
The second option is to convert the slug to title case. You can do this by using Laravel's string class. For example:
$categoryName = Str::title($slug);
However there are a few issues with this approach. Firstly, when creating a slug the url will remove characters that are not safe, for example an apostrophe. This means if you have a pluralised category name it won't match when converting the slug back to title case.
Secondly, by using code to transform strings in order to match a record in the database you are at the mercy of the service class. While the functionality of Str::title is unlikely to change, it could in theory which could then mean you have to change code later on down the line.
Conclusion
Overall, I would recommend going with the first approach. You have much better data integrity and less chance of things going wrong further down the line. So if I were you I would create a new migration to add a slug column to your categories table and then populate each category with its own slug. Then search for a category based on the slug column when querying your eloquent model.

Route/API convention questions

I have a web page where I have products and product categories, I have many pages to show data like where I show products belonging to a category, I'm scratching my head about how to approach this.
//Uses ProductController, shows products
Route::get('/products/category/{id}', 'Web\ProductController#productsCategoryId');
//Uses ProductCategoryController, shows products too
Route::get('/product-category/{id}/products','Web\ProductCategoryController#productCategoriesIdProducts');
I have two routes which show the same data, both show products belonging to a category, my heart tells me I should go for the first one in ProductController since I'm ALWAYS showing products, products are the main player per se but I have also seen the second route pattern used, then there's a third option I just thought.
What about forgetting about verbose routes and using query params:
/products?category=1
Boom, afaik if I do this there would be a single entry point in my controller and from that method depending on the query params I would show different pages, index.blade, show.blade, category.blade.
Using query params make me understand/read the url better imo but I'm worried about having a single method with a bunch of if conditionals is the way to go about this...
I'm open to all kind s of suggestions.
Try this one
Route::get('/products/category/{id}?category', 'Web\ProductController#productsCategoryId');
category=1

Routing codeigniter with unlimited params

I have a controller Categories with action index and params(params will contain category name) which makes my url http://localhost/categories/index/(category_name)
I want my url to be written like this
http://localhost/(category_name)
But i also have sub categories and more deep level sub categories. So now my url should be written like this
http://localhost/(category_name)/(sub_categories)
or more deep level
http://localhost/(category_name)/(sub_categories)/(sub_sub_categories)
Is there a way to route my url to unlimited params of the action.
The below code is working
$route['(.+)'] = 'categories/index/$1';
but it affects to all the controllers and no other controllers seems to be working
I want to know is there another way to achieve the same.
Thanks!
You can use uri_to_assoc(). Check this page.

Wordpress - Make category.php list posts from subcategories as well

I'm building a blog where three people will be writing, but they will have a separate section on the site. The structure is built upon categories and looks like this:
User one
Clothes
Fashion
Life
User two
Family
Life
User three
Family
Friends
Life
I've set all three users as writers and used the plugin Restrict Categories in order to lock their categories to the sub-categories the matching each top level category.
Now here comes the question, if I visit http://site.example/category/user-one/ I want to have a listing of all the posts, including the sub-categories since there will be no actual content in the top level category that you are browsing.
I've tried making this using filters bound to pre_get_posts but I still can't get it to work. Does anyone else here have any ideas?
I've also given some though into actually creating a multisite network for the purpose, but I then realized it will be hard to fetch posts from all the networks at once.
Thanks in advance, Jonathan
#Jonathan: Not sure if I am misinterpreting what you are hoping to achieve, but given that each author will already have their own 'author' page which lists all their posts (if your theme includes this or something you could create or customise), there may not really be a need for Users 1-3 to be their own category?
Going back to your question, for listing subcategories, perhaps https://wordpress.stackexchange.com/questions/13485/list-all-subcategories-from-category might be of some help.
As for listing posts, to keep things simple, I reckon you might be able to use e.g. get_posts (http://codex.wordpress.org/Template_Tags/get_posts) and build custom arguments, perhaps in a loop if you prefer to use one instead of slug/id specific category templates.
http://codex.wordpress.org/Category_Templates
If it's any help, Bainternet actually created a plugin that makes life a little easier to define category templates: http://wordpress.org/plugins/custom-category-template/

CodeIgniter Best Practice Items List

I'm creating an ebay-style (but more simplistic) shop in CodeIgniter and I'd like to know the best way to handle the items code/controllers.
At the moment, I've got a Category controller which is the main controller (in routes). /category/id is supposed to show a list of items for a specific category, and /category or / shows all items.
The category index($id=0){} in the controller loads the category helper which generates the category listing, then I echo it out in the view.
Now I'm up to the stage of adding the items aspect... Users need to be able to add items, view specific items, and the category code needs to be able to show all items or a specific category of items.
I was thinking of having a items controller with add_item, view_item, however now I'm wondering how I should be fetching the category listing from within the categories controller.
Should I have a items helper that loads the items model, fetches the list of items based off the category, assigns the list to a variable and echos the list? And when a user wants to view a specific item it loads the item controller view_item, and for adding add_item etc?
I also want the categories to display whilst they're viewing an item, so if I do it this way I'll also need to load the category helper within the items controller... Is this bad practice due to code repetition?
In short, here's what I would do.
/, Shows all items.
/category/xyz, Shows all items of category XYZ.
/item/view/xyz, Shows item XYZ.
/item/add, Adds an item.
...
It's normal to reuse your models across your controllers. It would be scary otherwise; it would mean a lot of code duplication. It's also normal to reuse your helper as much as possible. That's the goal of an helper! To implement a function that is reused at a lot of places. When you start to do copy + paste of the same lines, that's when you are not doing reuse. Create a function and reuse it.
Keep in mind,
Models deal with your data. (Categories, items, bid, ...)
Controller deals with your HTTP requests and responses. (Loading the right models, outputting the right views, ...)
Helper deals with frequent operations. (On your models, on your views, on your requests, ...)
Hope this helps.

Categories