Follow up from #33284 to add the missing style type value. This value
was originally meant for just categories but it makes things much easier
(and more complete) to add these values for other hashtag data types
like tags/channels etc, especially since they have default `icon` values
already.
Chat inline onebox links should open in a new tab with the help of chat
decorators by appending the `target="_blank"` attribute. I suspect this
may have been accidentally broken during a refactor in #31309
The issue was that the element that we pass into the decorator has
changed, meaning that the selector in the decorator would never find
inline links in cooked messages.
This adds a link for each authentication providers that are listed in
/my/preferences/account in the "Associated Accounts" section.
This is particularly useful when Discourse is being used in the PWA or
in the DiscourseMobile app where there's no browser bar available and
the only way to visit the provider's website is to open a browser
window.
That way, they can _just_ click the provider's name.
Internal ref - t/156255
---
**BEFORE**

**AFTER**

When fetching a model using the `model` step in a service, if that model
is an `ActiveRecord` object, we check if it’s in a valid state. While
this is useful when manipulating the model or when we create a new one,
it’s not the case for a model we just pulled from the DB, as it should
be valid.
In some cases, running the validations can be costly (it can lead to N+1
queries if the model validates associated items for example).
This patch introduces a small optimization by checking if the model has
any pending changes on it, thus requiring validation. If that’s not the
case, we just skip the validation part, as the model should be valid
anyway.
Adds the missing `style_type` that is used to decorate hashtags in core.
All chat channels currently use an icon by default, so declaring the
style type on the channel hashtag data source makes this more complete.
This would happen in the following scenario:
- select a tag
- save the automation
- unselect the tag
- save the automation
You would end up with a field having `[]` as value instead of `nil`.
This can cause issues in the logic of scripts and triggers as they might
consider the value as present.
When category lazy loading was disabled, chat channel CSS classes were
not being inserted into the page markup. This meant that they would not
be styled correctly in the markdown editor preview.
When we migrated to the full page /login, we added a nice feature that
will automatically redirect a user to the idp if it's the only way they
can log in, thus avoiding unecessary click.
But when logging out, we would redirect to the /login page which would
start the /login process by automatically redirecting the user to the
idp...
The fix is easy, redirect back to `/login-required` after logging out
instead. This will show the "splash" screen that asks the user to either
log in or sign up.
Note: I also removed the `Discourse::Utils::EMPTY_KEYWORDS` since it was
its last occurence and I'm pretty sure we dropped support for Ruby 2 a
while ago...
Internal ref - t/156834
This PR takes the localization features out of "experimental" to prep
for the announcement
- rename settings and gives them its own area
- `experimental_content_localization` to `content_localization_enabled`
- `experimental_content_localization_allowed_groups` to
`content_localization_allowed_groups`
- `experimental_content_localization_supported_locales` to
`content_localization_supported_locales`
- `experimental_anon_language_switcher` to
`content_localization_anon_language_switcher`
- migration
- related to https://github.com/discourse/discourse-ai/pull/1439
| screenshot 📸 |
|---|
| <img width="964" alt="Screenshot 2025-06-17 at 5 06 32 PM"
src="https://github.com/user-attachments/assets/9a8b2c38-c846-4fc9-8ddd-815c45cc3d0e"
/> |
The `on_update` callback of triggers is called with previous fields and
new fields, values. However since a recent change:
https://github.com/discourse/discourse/pull/32810 this relationship is
cached and would cause previous fields to equal new fields. This commit
ensures we are refreshing the relationship before calling the
`on_update` callback.
This is a follow up to b02bc707dec12c607511d4a95c7d791f63131b49 where
the `S3Helper#upsert_tag` method was introduced. Using the method
resulted in an error being thrown because the key was incorrect.
Currently when a model is not found, we raise an `ArgumentError`
exception and that exception is stored in the resulting context object.
However, since we’re also storing unexpected exceptions, this default
exception can pollute the context object when we need to inspect it or
act on it.
This patch addresses that issue by raising a custom exception instead,
and we then discard it from the context object.
Adds a Discourse ID authenticator. Not available for use in production
just yet, but soon communities will be able to use this service to let
users authenticate using a central Discourse ID account.
Includes a support for a `/revoke` action, allowing users to log out of
multiple client instances from a central auth service.
Internal ticket: t/155397
---------
Co-authored-by: Loïc Guitaut <loic@discourse.org>
Strips the site's base URL and `https`/`mailto` protocols from the link
toolbar display

Refactors the toolbar to use getters instead of function calls, re-uses
`DButton` for the `href` toolbar item instead of a custom `a` tag, fixes
a bug where we passed a translated string to DButton's `label` that
expects a i18n key, and adds support to “disabled” buttons.
Slightly simplifies the toolbar implementation by extracting one step of
indirection removing `toolbarButton` from d-editor.