HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Any example of using the new sort & filter module?
@Link wrote in the initial change list for 2.3 "Add discussions sort & filter module for developers."
I wonder if this feature is used anywhere and how it can be used.
2
Comments
What I think is meant is that there are now some sort of "sort keys" available. Look at this:
If you create and apply a custom sort key in a DiscussionModels AfterDiscussionSummaryQuery event handler, you are able to sort the result any way you like.
I remember we have spoken about the problem that you couldn't have individual sort directions before. This is a comfortable solution!
You can do some more nice things, try that:
That would make that sort only apply to categories 3, 6, 11
And even some fun stuff like this:
To put it short: without further changes you are able to sort by any column from tables Discussion and UserDiscussion
Although that can be used like that, I guess I'm on the wrong track. I found this in the source code:
So they offer a way to use them as predefined request query parameters (although I haven't looked at how to apply them). But based on that comments you would be able to define a sort and a filter and the result of a http request would return discussions based on the provided filter and the provided sort key.
I assume it is used in or useful for the API, but honestly I don't know and that is only wild guessing...
Oh yes, it is already working here: https://vanillaforums.org/discussions?sort=new
This is excellent, @R_J .
But can we sort by Categories and tags?
site/categories/books?tag=tragedy
So that discussions will be shown only if they fall in the category and tutorial.
This would be phenomenal
The DiscussionModel supports "sorts" and "filters". if you say it should "only show" we are talking about filters. While there are default sorts defined in the DiscussionModel, there are no filters.
You would have to create a plugin that would consume site/discussions?category=books&tag=tragedy and add the corresponding filters to the DiscussionModel.
When looking at the DiscussionModel, you'd find multiple methods that are dealing with filters.
Although I'd say that doing such a restriction by using filters would be the best approach (it is not the only way to do so), I wouldn't see the best "starting point". When restricting what the /discussions show, I'd normally use
discussionModel_beforeGet_handler
, but this is to late in program flow. Based on that comment:I'd try my luck with
__construct
andDiscussionModel::instance()->
...Sorry, I know this all sounds like Chinese if you are not used to writing plugins for Vanilla but I do not know about your skills. All in all it shouldn't be that hard. If you don't feel like trying it out by yourself I might be able to throw something together later this weekend...
Well, having such a filter is one aspect. You would need to think about how to let the user choose something like that and implementing such an interfece would be the real task here.
The UI part and implementation is the ease and dream part. But finding the file/code to piggyback on is the trick I have been digging for all night .... trying to see what handles the request.
Here is an example https://meta.discourse.org/tags/c/installation/sso
I found out that a filter wouldn't be the best approach - possible but not so clever. I'll try to assemble something based on the BeforeGet event and show it to you
We already have a way to sort by tagged. It’s built in but we don’t have much UI for it. Example here
@charrondev is that the native feature or did I miss something?
IIRC, that sort, is site wide, it will list all discussions from all categories.
I am dreaming some door that opens all kinds of possibilities from url parameters like these....
site/discussions?category=books&tag=tragedy
site/discussions?category=drama&tag=tragedy
site/discussions?category=books&tag=comedy
site/discussions?category=drama&tag=comedy
site/discussions?category=cms&tag=php&sort=mine
site/discussions?category=books&tag=tragedy&sort=unread
site/discussions?category=books&tag=tragedy&sort=top
site/discussions?category=books&tag=tragedy&sort=unread
With 50% already provided by Vanilla, you will only have to implement this part:
Now you only need the UI part which will builds requests like site/discussions/tagged/TheTagName?category=TheCategorySlug&sort=new
For sort=mine and sort=unread it would require some more work
So, this went from necro
to pure hot baking sizzling explosive vibrancy
I once created a dropdown on that page (for another reason). This plugin might be helpful: https://open.vanillaforums.com/addon/latest-plugin
You would need to get CategoriesModel::categories() and build a dropdown consisting of the Name and UrlCode column
@donshakespeare It would be awesome to get this type of thing in core but I fear we won't be able to do until we make some backwards incompatible changes around the endpoint. The constant challenge with these long-standing pages is that because of how unstructured the old event system is, it's incredibly difficult to refactor.
We've had these types of filters in some internal mockups for a while, but when we do put them in core, I would expect them to be part of an opt-in flag for a totally new discussions page that starts over with some more structured & efficient methods of hooking in.
In the meantime @R_J has you on the right track with this I think. I'll see what I can do with the discussion as far as getting rid of the necro and moving the category.
@R_J a slight correction
would inadvertently replace all the existing data in Wheres like the crucial d.DiscussionID
I mended it to
You have done a marvelous deed today. Cheers!
@donshakespeare - I just saw this discussion. All of @R_J 's suggestions are terrific and I have learned a lot from him. You may get some ideas from a very old plugin I wrote long ago called filterdiscussions long before Vanilla provided some builtin support for this. If you run on 2.8 you will need to change the following line from:
class FilterDiscussion extends Gdn_Plugin {
to
class FilterDiscussionplugin extends Gdn_Plugin {
Then, please read the long comment in the plugin source - there is no other way you will know how to actually use it...
Eventually you will be able to filter discussions (just filter, not sort) based on any field in the discussion table (including columns added by other plugins). The plugin takes parameters from the url in a specific syntax, parses them, and adjust the sql parameters to obtain the desired filter. Since it is unlikely that end users will use that syntax, the real aim of the plugin is to be invoked by other plugins (e.g. addmenuitems) that internally use that syntax.
Hope this will give you some inspiration.
@rbrahmson yes I agree with you on @R_J . I would like to have what he eats for breakfast. I am sure it is nothing short of pure clear code.
As for your FilterDiscussion, it just blew out of the water, and I am not sure where I have landed. This thing is pure magic. First, is it safe!? I am still shaking ...
Filtering is so important for a big forum and this plugin even beats some search mechanics.
I will build a little UI for it to help my users fine-tune their search. Awesome job!
Before you go and write more customization take a look at the saved filters option that does not reveal the parameters. Then take a look at the sidepanel links plugin as ways to invoke the saved filters. The combination of saved filters and sidepanel links may already give you what you need.
Also, as for safety, in addition to hiding the syntax in named saved filters you can control which columns can be used as filters through the plugin settings.
Yes, the "saved filters" is simply genius, well thought ahead on that one!
Also, just in case, I replaced all $_GET with Gdn::request()->get() in the plugin.
Also ...
I have this saved filter... Tags=EQ:6&CategoryID=NE:321&InsertUserID=EQ:{userid}.
Accessed by /discussions/FilterDiscussion?!filter=mine
And then I was gonna ask if there was a way to make the filter accept dynamic stuff? And then I saw that function you exposed .... that's just brilliant!
So I am doing
In this function