-
-
Notifications
You must be signed in to change notification settings - Fork 834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slug Driver Support #2456
Slug Driver Support #2456
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO:
- Add an extender for adding slugging drivers to models. Add integration tests for that extender
- Can we encapsulate any of the direct querying done in the drivers into the User / Discussion Repository classes, and inject those via DI?
- @flarum/core Confirm our stance on calling the full slug (whatever it might be)
slug
, and serializing it as such to the frontend. This conflicts with the current naming used by the tags extension (so that's a breaking change if we adopt it there), but it would be nice to use a common convention, and justslug
seems sensible (I would also be fine withfullSlug
, but Clark I know you have concerns about that, and I see where you're coming from). - Decide whether we want to keep the
toResource
URL generator; if so, adopt throughout the core codebase where possible, and add an extender / tests for it - Figure out what to do with frontend code that obtains discussion ID from the slug. This happens in 2 places:
- DiscussionListItem's
isActive
, which can be overriden, but could also useapp.current.discussion
(which might make more sense). - DiscussionPageResolver's
getDiscussionIdFromSlug
helper. I don't think there's a way to universalize this one, but IMO we should move it onto theDiscussionPageResolver
class so it can be overriden to generate the key in some different manner if needed by an extension.
- DiscussionListItem's
Regarding @askvortsov1 points above
|
@askvortsov1 I'm going to rebase this tonight when I get home so we can fix whatever Admin stuff we need to (Admin UX got merged) and from there this PR is good to go if I'm not mistaken? |
Yep! It should be good for full review then. |
f2c7030
to
1eb316b
Compare
Rebased this onto the master with the Admin UX changes, everything looks great and works correctly in my testing. We still need to create the translations however. |
[ci skip] [skip ci]
[ci skip] [skip ci]
[ci skip] [skip ci]
[ci skip] [skip ci]
[ci skip] [skip ci]
d5e6c2d
to
2ac869f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking amazing, I am literally stunned by the implementation. Well done!
I left some considerations, questions; please have a look.
@@ -35,7 +46,7 @@ protected function getDefaultAttributes($discussion) | |||
|
|||
return [ | |||
'title' => $discussion->title, | |||
'slug' => $discussion->slug, | |||
'slug' => $this->slugManager->forResource(Discussion::class)->toSlug($discussion), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be easier to have a method on the abstract model instead?
$discussion->slugger->slug();
So that we resolve the slug manager late here as well, plus we can reduce the overhead on every, single class that tries to resolve the slug manager..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused how that would work tbh. I'm very wary about adding stuff to AbstractModel unless it absolutely affects ALL models, which isn't the case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if it's a trait one can apply to the model, eg Discussion has the Sluggable trait. It adds that trait, sets the property protected $slugger = DiscussionSlugger::class;
and the trait handles the rest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this. It adds unnecessary static stuff to the models, and I'd really prefer to move away from that as much as we possibly can because it's unnecessary leakage of global state. It also makes the extension mechanism a lot more hacky (similar to what I had to do with #2460), which I really didn't like and will revisit again after stable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! nice work!
I believe it'd be better to have IdOnlyUserSlugDriver
here instead of the nicknames extension.
If I make for example another extension that adds a different user display name driver, the admin might want to use this IdOnlyUserSlugDriver
but then I'd have to also add it to my own extension, because it only resides within the nickname extension.
Let me know what you think.
this.slugDriverOptions[model] = {}; | ||
|
||
app.data.slugDrivers[model].forEach((option) => { | ||
this.slugDriverOptions[model][option] = option; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the keys getting localized somewhere ? I mean default
and idOnly
for example (same with display name drivers) They don't seem to be, at least the option's label not the key itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, and mail drivers aren't either. That's a limitation worth revisiting later IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now, something like app.translator.trans('core.admin.basics.slug_drivers.${option}')
wouldn't work, since extensions are adding drivers, and that means they couldn't add locales for the drivers anyway.
The solution would need to be more sophisticated. Yeah worth revisiting it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it'd be better to have
IdOnlyUserSlugDriver
here instead of the nicknames extension.
On second thought, I agree with this, and that goes for IdOnlyDiscussionSlugDriver
as well (and that doesn't break anything with the frontend stuff since the ID is still first).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have nothing else to add, it all looks good to me.
Just noting that we need of course to remember to add the id only drivers in core and to add the nicknames extension to composer.json
Partially Solves flarum/issue-archive#203
Changes proposed in this pull request:
Reviewers should focus on:
Confirmed
composer test
).Required changes: