Skip to content

[WIP] Theme i18n #21490

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

Closed
wants to merge 15 commits into from
Closed

Conversation

cathysarisky
Copy link
Member

@cathysarisky cathysarisky commented Oct 31, 2024

Don't look at this one. I replaced it with a better one!
#23161

cathysarisky and others added 2 commits October 31, 2024 13:46
commit 361d88b
Merge: fcc6314 4c79887
Author: Cathy Sarisky <[email protected]>
Date:   Thu Oct 31 13:23:45 2024 -0400

    Merge branch 'main' into theme-i18n

commit 4c79887
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Thu Oct 31 16:39:05 2024 +0000

    Update dependency compression to v1.7.5

commit fe2cff4
Author: Hannah Wolfe <[email protected]>
Date:   Thu Oct 31 16:36:44 2024 +0000

    Moved search i18n behind labs flag (TryGhost#21488)

    - When we added i18n for search we missed gating it behind the i18n flag.
    - There aren't that many translations for search yet, so it's likely not many have noticed yet
    - We'll remove the flag soon, but until then, adding the flag for consistency :)

commit 3ecfe08
Author: Michael Barrett <[email protected]>
Date:   Thu Oct 31 16:34:53 2024 +0000

    Added failure state for reply in admin-x-activitypub (TryGhost#21487)

    no refs

    Added a failure state for when a reply fails to be sent

commit f601ab3
Author: Cathy Sarisky <[email protected]>
Date:   Thu Oct 31 11:32:34 2024 -0400

    ✨ Added "exclude" option for customizing {{ghost_head}} (TryGhost#21229)

    no ref

    {{ghost_head}} is huge, and some power-users and theme creators want the
    ability to customize what it contains. This PR makes it easier for a
    theme to write custom schema, or to load a custom version of
    portal/comments/search/etc, or to minimize load times by not loading
    scripts where they aren't needed, in a theme-specific way.

    Because ghost_head is controlled at the theme level, this gives folks in
    managed hosting the new ability to load a different version of the
    included app scripts (by preventing ghost_head from writing them and
    adding them in manually).

    Usage example: ` {{ghost_head exclude="search,portal"}} `

    (empty array)
    	No changes to current behavior

    search
    	The built-in sodo-search script
    Includes adding the click event listener on buttons, generating the
    search index, and the UI.

    portal
    	The portal script
    Handles sign-in and sign-up, payments, tips, memberships, etc, and all
    the portal data-attributes.

    announcement
    	The announcement bar javascript
    If you'd like to use the announcement bar admin settings but not have it
    [mess up your CLS
    metric](https://www.spectralwebservices.com/blog/announcement-bar-a-review/),
    this is for you.

    metadata
    Skips HTML tags for meta description, favicon, canonical url, robots,
    referrer
    	Important for SEO

    schema
    	The LD+JSON schema
    	Important for SEO

    card_assets
    	Loads cards.min.css and .js
    Needed on any page with a post body, unless your theme replaces them
    all. Assets can also be selectively loaded with the [card_assets
    override](https://ghost.org/docs/themes/content/?ref=spectralwebservices.com#editor-cards)

    comment_counts
    	Loads the comment_counts helper
    Needed if the page is using {{comments}} or data-ghost-comment-count
    attribute

    social_data
    Produces the og: and twitter: attributes for social media sharing and
    previews
    	Required for good social media cards

    cta_styles
    	Removes the call to action (CTA) styles
    Used for member signup and CTA cards - may be overwritten by your theme
    already

commit 7e50a40
Author: Kevin Ansfield <[email protected]>
Date:   Thu Oct 31 14:10:31 2024 +0000

    Improved error log when Twitter enhanced oembed fails

    ref https://linear.app/ghost/issue/ONC-506

    - adding `context` with the returned API response makes the logged error much more useful as without it we only log the status code which misses any details for why the failure occurred

commit 1d429b8
Author: Cathy Sarisky <[email protected]>
Date:   Thu Oct 31 09:41:39 2024 -0400

    🌐✨Added i18n for newsletter strings (TryGhost#21433)

    no issue

    This PR adds the ability to translate the strings that appear in the
    newsletter as boilerplate text, using i18next.

    Variables are in single mustaches ( `{date}` ) in the translation
    strings (rather than `{{date}}`), because these strings occur both the
    email template.hbs and also .js files. That necessitated a separate
    namespace.

    This PR also includes changes to the newsletter button ("more like
    this", "less like this", "comment") that were previously delivered on
    desktop as images that included the text. @sanne-san provided a rework
    that removed text-as-image from the desktop buttons, and allows more
    shared code between the two layouts, along with making the buttons
    translatable.

    Example usage - handlebars
    ```
    <h3 class="latest-posts-header">{{t 'Keep reading'}}</h3>

    {{{t 'By {authors}' authors=post.authors }}}
    ```
    (NOTE: triple { required because of possible & )

    Example usage - javascript
    ```
                    getValue: (member) => {
                        if (member.status === 'comped') {
                            return t('complimentary');
                        }
                        if (this.isMemberTrialing(member)) {
                            return t('trialing');
                        }
                        // other possible statuses: t('free'), t('paid') //
                        return t(member.status);
                    }
    ```

    ---------

    Co-authored-by: Sanne de Vries <[email protected]>
    Co-authored-by: Steve Larson <[email protected]>

commit dd2ed27
Author: Michael Barrett <[email protected]>
Date:   Thu Oct 31 11:40:41 2024 +0000

    Removed unused `useAllActivitiesForUser` hook and related code in admin-x-activitypub app (TryGhost#21482)

    no refs

    Removed unused `useAllActivitiesForUser` hook and related code. This was
    a left over from when we added paginated activities

commit 085afde
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Thu Oct 31 10:53:43 2024 +0000

    Pin dependency clsx to 2.1.1

commit 45711e1
Author: Djordje Vlaisavljevic <[email protected]>
Date:   Thu Oct 31 10:50:51 2024 +0000

    AP design bugs (TryGhost#21395)

    - Fixed links in profile description
    - Stripped post content
    - Fixed grey bg in Avatars
    - Installed `clsx`

    ---------

    Co-authored-by: Michael Barrett <[email protected]>

commit 4f46624
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Thu Oct 31 10:11:27 2024 +0000

    Update Koenig packages (TryGhost#21480)

commit 824efc7
Author: Djordje Vlaisavljevic <[email protected]>
Date:   Thu Oct 31 10:07:52 2024 +0000

    Added UUID as data attribute to posts in all views (TryGhost#21470)

    ref
    https://linear.app/ghost/issue/AP-404/add-uuid-as-a-data-attribute-in-the-dom-for-easier-db-lookup

    - This will allow us to find posts in the DB

    Co-authored-by: Michael Barrett <[email protected]>

commit becfd13
Author: Djordje Vlaisavljevic <[email protected]>
Date:   Thu Oct 31 09:58:47 2024 +0000

    Refactored handleViewContent so it can be reused (TryGhost#21468)

    ref
    https://linear.app/ghost/issue/AP-540/clicking-comment-icon-on-posts-and-likes-tabs-of-your-profile-doesnt

    - We want to open posts in the drawer from multiple views (Inbox,
    Profile etc.) and this change allows us to do so by pulling
    `handleViewContent` from `Inbox.tsx` into a utility function. At the
    same time, we’ve simplified the function so it uses less props to
    achieve the same functionality.
    - Also added a simple fix for scrolling the reply-box into view when
    opening a long `article` by clicking on the reply icon. We probably
    still need to figure out a more robust solution, because the height of
    the `iframe` and the fact it takes some time to load it sometimes gets
    in the way.

    Co-authored-by: Michael Barrett <[email protected]>

commit 5f59dda
Author: Michael Barrett <[email protected]>
Date:   Thu Oct 31 09:38:52 2024 +0000

    Updated replies implementation to use thread mechanism in admin-x-activitypub (TryGhost#21465)

    refs:

    - https://linear.app/ghost/issue/AP-439/seeing-parent-post-for-replies
    - https://linear.app/ghost/issue/AP-481/reply-ui
    -
    https://linear.app/ghost/issue/AP-482/replies-to-a-post-should-be-visible-when-opening-it

    Updated the replies implementation to make use of the new thread
    mechanism. This allows for a more sane approach to handling replies as
    well as making it possible to show the parent of a reply in the UI

    ---------

    Co-authored-by: Djordje Vlaisavljevic <[email protected]>

commit ea6d3a0
Author: Daniel Lockyer <[email protected]>
Date:   Thu Oct 31 09:45:14 2024 +0100

    ⚡️ Optimized fetching strings from the settings cache

    fix https://linear.app/ghost/issue/ENG-1105/settingscacheget-is-slow

    - through profiling and flamegraphs, we can see that `_doGet` is one of
      the bottlenecks during high traffic times, sometimes taking up to 20%
      of the CPU time when hammering Ghost with `wrk`
    - this is because, for the majority of settings cache lookup, we're
      running `JSON.parse`, which blocks the main thread
    - whilst we're only parsing small strings, we're doing it a LOT,
      sometimes hundreds of times per request, which adds up
    - this code just throws most deserializing at `JSON.parse`, so if we can
      stop it from doing that, it'd be a huge win
    - my initial attempts here were to convert the _doGet function to a
      smarter deserializing, by looking up `cacheEntry.type` and acting
      accordingly
    - however, it became a bit of a logical nightmare, and difficult to
      reason about for now (i still think we should do it)
    - therefore, I'm just doing to add a hotpath fix to catch 99% of
      usecases, which is checking the type of the cache entry and returning
      the value if it's a string
    - on a trivial benchmark locally, this causes Ghost to return 30% more
      requests per second!!

commit fa31176
Author: Sodbileg Gansukh <[email protected]>
Date:   Thu Oct 31 13:43:39 2024 +0800

    Removed Prata font (TryGhost#21478)

    ref DES-926

commit e01b952
Author: Sodbileg Gansukh <[email protected]>
Date:   Thu Oct 31 13:30:25 2024 +0800

    Made the tabs sticky in design and newsletter settings (TryGhost#21477)

    ref DES-927, DES-928

commit 87e24f6
Author: Ronald Langeveld <[email protected]>
Date:   Thu Oct 31 12:28:44 2024 +0900

    Revert "Enhanced Comments Ordering for Best Liked Sorting (TryGhost#21473)" (TryGhost#21475)

    This reverts commit fd18a39.

commit fd18a39
Author: Ronald Langeveld <[email protected]>
Date:   Thu Oct 31 10:44:15 2024 +0900

    Enhanced Comments Ordering for Best Liked Sorting (TryGhost#21473)

    ref PLG-220

    - Improved `getBestComments` service to paginate correctly since we're
    using a custom query to determine the top comments that goes beyond the
    scope of what `findPage` is capable of.
    - Updated CommentsController and CommentsService to support custom order
    parameters.
    - Added tests

commit fe9b019
Author: Chris Raible <[email protected]>
Date:   Wed Oct 30 12:39:41 2024 -0700

    Cleaned up browser test output in CI (TryGhost#21462)

    no issue

    - The browser test output in CI is really noisy, because the `NX_DAEMON`
    doens't run in CI, but we're trying to use NX to watch and rebuild the
    typescript modules. This is outputting a ton of "NX Daemon is not
    running" type of errors, which make it difficult to sift through the
    actual test results.
    - We don't actually need to watch the typescript files, we just need to
    build them once before starting. This is defined as an NX dependency for
    the browser tests target, so we don't need to explicitly build the TS
    packages at all. Removing the typescript watch & build command removes
    the noisy errors, without impacting how the tests actually run.

commit 30fc2f3
Author: Chris Raible <[email protected]>
Date:   Wed Oct 30 11:56:10 2024 -0700

    Added `ps` dependency to Dockerfile (TryGhost#21471)

    no issue

    - When stopping `yarn dev` with ctrl+c in the dev container, you'd get
    an error because the container doens't have `ps` installed, which is
    used by node under the hood. Adding this dependency fixed the error so
    `yarn dev` (and other commands) exit cleanly

commit fbad9f1
Author: matsbst <[email protected]>
Date:   Wed Oct 30 16:38:46 2024 +0100

    🌐 Added new and improved Norwegian translation (TryGhost#21452)

    - New and improved Norwegian translation. All strings translated.

commit 97e756e
Author: Steve Larson <[email protected]>
Date:   Wed Oct 30 09:18:06 2024 -0500

    Bumped Portal and search packages (TryGhost#21467)

    no ref

    These had new minors shipped without a bump in Ghost core.

commit fcc6314
Merge: 2ed00b6 98c06f8
Author: Cathy Sarisky <[email protected]>
Date:   Wed Oct 30 09:35:24 2024 -0400

    Merge branch 'main' into theme-i18n

commit 98c06f8
Author: Kevin Ansfield <[email protected]>
Date:   Wed Oct 30 11:47:15 2024 +0000

    Fixed removal of event tracker requests in Sentry

    no issue

    - filtering was previously added to breadcrumbs but that wasn't enough to clean up Sentry reports
    - added filtering to the `beforeSend` hook too so reports don't get cluttered with unhelpful XHR noise

commit cca6a38
Author: Ronald Langeveld <[email protected]>
Date:   Wed Oct 30 19:06:11 2024 +0900

    Patched Comments UI v0.20.1 (TryGhost#21464)

    no issue

    ---------

    Co-authored-by: Sanne de Vries <[email protected]>

commit 119a913
Author: Sanne de Vries <[email protected]>
Date:   Wed Oct 30 09:56:42 2024 +0100

    Fixed comment form being cut off at the top (TryGhost#21463)

    No ref

commit d4d45de
Author: Chris Raible <[email protected]>
Date:   Tue Oct 29 19:22:58 2024 -0700

    Added github-cli and some zsh plugins to dev container (TryGhost#21460)

    no issue

    - The Dev Container didn't have the Github CLI installed, so this adds
    that using Dev Container
    "[features](https://containers.dev/implementors/features/)"
    - It also adds oh-my-zsh and a few plugins that are nice to have when
    developing.

commit eb9483a
Author: Chris Raible <[email protected]>
Date:   Tue Oct 29 15:21:46 2024 -0700

    Fixed git remote configuration in dev container (TryGhost#21459)

    no issue

    - When creating a dev container, the onCreateCommand script will try to
    setup the git remotes according to the environment variables defined for
    e.g. `$GHOST_UPSTREAM`. There was a bug that caused the `origin` remote
    to successfully be renamed to `$GHOST_UPSTREAM`, but the `origin` remote
    was not being created successfully on the first try. This commit fixes
    that bug.

commit 1d24b2c
Author: Chris Raible <[email protected]>
Date:   Tue Oct 29 14:52:44 2024 -0700

    Added configuration of git remotes to dev container setup (TryGhost#21458)

    no issue

    - Added function to Dev Container onCreateCommand to setup git remotes
    when creating the Dev Container
    - If `$GHOST_UPSTREAM` is set, it will rename the default `origin`
    remote to its value
    - It will also update the remotes for the submodules, otherwise `yarn
    main` will fail
    - If `$GHOST_FORK_REMOTE_URL` is set, it will add it as `origin`, or the
    value of `$GHOST_FORK_REMOTE_NAME` if set.
    - If `$GHOST_FORCE_SSH` is set to `true`, it will change all remotes
    URL's to use ssh instead of https

commit c299051
Author: Djordje Vlaisavljevic <[email protected]>
Date:   Tue Oct 29 21:55:30 2024 +0100

    Fixed incorrect actor passed from like notifications (TryGhost#21451)

    ref https://linear.app/ghost/issue/AP-541/incorrect-object-loaded-on-like-notifications

    - We were passing the wrong `actor` info from `like` notifications. We should be using `activity.object.attributedTo` instead.

commit 71fb9f8
Author: Chris Raible <[email protected]>
Date:   Tue Oct 29 13:03:49 2024 -0700

    Converted dev container's onCreateCommand to JavaScript (TryGhost#21457)

    no issue

    - The onCreateCommand was previously a bash script, which made it a bit
    more challenging to read and make changes to it. This commit converts it
    to JavaScript so it will be easier to make updates to it.

commit 2ed00b6
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 14:38:53 2024 -0400

    bad in exactly every way, but a start!

commit 856dd1f
Author: Kevin Ansfield <[email protected]>
Date:   Tue Oct 29 17:46:35 2024 +0000

    🐛 Fixed "Access Denied" error when accepting staff invite

    ref https://app.incident.io/ghost/incidents/117

    - the authenticate call made as part of signup was missed as part of the update when we adjusted the params for `cookie` authenticator's `authenticate` method in Admin so it could switch behaviour for 2fa
    - fixed the authenticate call params and updated our mocked `/session` endpoint to check for expected POST data which would have let tests catch this error

commit 28a9a43
Author: Michael Barrett <[email protected]>
Date:   Tue Oct 29 17:07:01 2024 +0000

    Prevent replies from being shown on profile page in admin-x-activitypub (TryGhost#21454)

    refs
    [AP-543](https://linear.app/ghost/issue/AP-543/posts-on-profile-should-not-include-replies)

    Filtered the posts on the profile page to only show `Create` activities
    that are not replies.

commit cc2fc1c
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 09:42:39 2024 -0400

    more snapshots.

commit e66ff34
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 09:31:28 2024 -0400

    fix snapshots in places I didn't know we had snapshots.

commit 3cc0380
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 09:19:39 2024 -0400

    more broken tests

commit 8456170
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 09:07:27 2024 -0400

    fix broken test

commit 253608a
Author: Steve Larson <[email protected]>
Date:   Tue Oct 29 07:49:25 2024 -0500

    Cover last lines in unit test

commit 2fc2c6a
Author: Sanne de Vries <[email protected]>
Date:   Tue Oct 29 13:17:05 2024 +0100

    Updated feedback button styling

    No issue
    - Removed all mobile feedback button code
    - Updated styling of feedback buttons to display in a single row on desktop and column on mobile

commit 4a8da45
Author: Daniël van der Winden <[email protected]>
Date:   Tue Oct 29 12:03:43 2024 +0100

    Fixed searchbar's X button overlapping with Settings' X button (TryGhost#21449)

    fixes
    https://linear.app/ghost/issue/DES-316/adminx-settings-search-overlaps-with-modal-close-x-when-in-mobile-view

    Regression, solved by removing an overexcited media query.

commit 156775b
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 06:46:45 2024 -0400

    test tweaks

commit 456af29
Author: Sanne de Vries <[email protected]>
Date:   Tue Oct 29 11:44:00 2024 +0100

    Fixed avatar initials being broken in comment form (TryGhost#21448)

    REF PLG-248

commit cc8a36c
Author: Djordje Vlaisavljevic <[email protected]>
Date:   Tue Oct 29 11:26:27 2024 +0100

    Fixed articles getting cut off in the drawer (TryGhost#21447)

    ref
    https://linear.app/ghost/issue/AP-542/articles-are-cut-off-when-viewed-in-sidebar

    - We now wait for the content of the iframe to load completely before
    determining the height needed to display it

commit ba30684
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 05:56:08 2024 -0400

    and the snap

commit fbe7250
Author: Cathy Sarisky <[email protected]>
Date:   Tue Oct 29 05:53:13 2024 -0400

    date localization problem fixed?

commit e6df621
Author: Michael Barrett <[email protected]>
Date:   Tue Oct 29 09:46:43 2024 +0000

    Updated ActivityPub collection retrieval to accommodate pagination (TryGhost#21393)

    refs
    [AP-526](https://linear.app/ghost/issue/AP-526/implement-pagination-for-fedify-collections)

    Updated followers, following, outbox and liked collection retrieval to
    accommodate pagination

commit 4b32a3d
Author: Sodbileg Gansukh <[email protected]>
Date:   Tue Oct 29 15:31:29 2024 +0800

    Fixed signup card button height (TryGhost#21446)

    ref DES-923

commit d6639fd
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 23:41:38 2024 -0400

    added a creation date - my mock is too good, and needs one to make the snapshots work!

commit f8ef2a1
Author: Fabien 'egg' O'Carroll <[email protected]>
Date:   Tue Oct 29 03:17:57 2024 +0000

    Fixed layout state sync issues (TryGhost#21443)

    refs https://linear.app/ghost/issue/AP-544

    useState was still called twice, we should have pulled that out - but
    instead passing values down for now

commit 4d35d31
Merge: abc4d7b 1c51718
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 23:09:05 2024 -0400

    Merge branch 'newsletter-t' of https://github.com/cathysarisky/Ghost into newsletter-t

commit abc4d7b
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 23:09:01 2024 -0400

    fix dates... again.

commit 1c51718
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 22:54:54 2024 -0400

    argh, package.json...

commit 071cf48
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 22:51:52 2024 -0400

    preliminary update of snapshots for translatable buttons

commit bde1755
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 22:24:49 2024 -0400

    make buttons translatable

commit 7922bcd
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 21:58:33 2024 -0400

    lint is hard

commit 2d29b78
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 21:53:53 2024 -0400

    better test

commit 6c0adf3
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 21:50:42 2024 -0400

    test wrangling

commit 6240f25
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 21:18:14 2024 -0400

    test fussing

commit 869ea0b
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 21:03:43 2024 -0400

    e2e test fix?

commit 01e5bdb
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 20:21:17 2024 -0400

    t fun.

commit 0cf65a0
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 20:12:10 2024 -0400

    only one failing test?

commit d0bf80b
Author: Chris Raible <[email protected]>
Date:   Mon Oct 28 16:14:04 2024 -0700

    Added `from` address to Dev Container's auto configuration (TryGhost#21442)

    refs
    https://linear.app/ghost/issue/ENG-1686/mail-auto-configuration-doesnt-work

    - Previously the `mail` configuration that is auto-generated didn't work
    because the `from` address wasn't being set, and requests were
    consequently failing due to some Mailgun internal validation.
    - This change requires the `MAILGUN_FROM_ADDRESS` environment variable
    to be set for it to automatically configure the `mail` block, and if it
    is, it adds it as `mail.from`. Now with all three of
    `MAILGUN_SMTP_AUTH`, `MAILGUN_SMTP_PASS` and `MAILGUN_FROM_ADDRESS`
    setup, transactional emails work out of the box in the Dev Container.

commit c1100c8
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 17:27:02 2024 -0400

    try building, probably fail lint.

commit 75948c6
Merge: 5581695 2c7de4e
Author: Ghost CI <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Mon Oct 28 20:53:37 2024 +0000

    Merged v5.98.1 into main

commit 2c7de4e
Author: Ghost CI <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Mon Oct 28 20:53:35 2024 +0000

    v5.98.1

commit 00bd31a
Author: Steve Larson <[email protected]>
Date:   Mon Oct 28 09:58:09 2024 -0500

    🐛 Fixed malformed `unsubscribe_url` in members api response (TryGhost#21437)

    no ref

commit 2b29812
Author: Sodbileg Gansukh <[email protected]>
Date:   Mon Oct 28 18:36:38 2024 +0800

    Fixed banner text color in dark mode (TryGhost#21427)

    ref DES-908

commit 3afc818
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 15:33:57 2024 -0400

    hating importing.

commit 49aec51
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 15:13:59 2024 -0400

    tweak imports again?

commit 35a639a
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 15:03:11 2024 -0400

    build error?

commit cb401ed
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 14:48:36 2024 -0400

    import issues

commit d8d5de5
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 14:35:36 2024 -0400

    issues with imports?

commit d095750
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 13:51:47 2024 -0400

    belly button lint?

commit d1eabc7
Merge: ea617f4 1774caa
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 13:47:30 2024 -0400

    Merge branch 'newsletter-t' of https://github.com/cathysarisky/Ghost into newsletter-t

commit ea617f4
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 13:47:28 2024 -0400

    date i18n

commit 1774caa
Merge: ea627fa 5581695
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 12:55:16 2024 -0400

    Merge branch 'main' into newsletter-t

commit ea627fa
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:32:23 2024 -0400

    add a test

commit 7f66b14
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:19:11 2024 -0400

    stray space = failed test :(

commit e88c57c
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:14:27 2024 -0400

    dangit lint

commit 8834ef6
Merge: 6ae2844 3c3aa27
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:10:20 2024 -0400

    Merge branch 'newsletter-t' of https://github.com/cathysarisky/Ghost into newsletter-t

commit 6ae2844
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:10:10 2024 -0400

    ah lint

commit 3c3aa27
Merge: 3a7c50f bf714ac
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 09:00:10 2024 -0400

    Merge branch 'main' into newsletter-t

commit 3a7c50f
Author: Cathy Sarisky <[email protected]>
Date:   Mon Oct 28 08:43:57 2024 -0400

    fixed!

commit 4960f84
Author: Cathy Sarisky <[email protected]>
Date:   Sun Oct 27 19:12:47 2024 -0400

    almost there!

commit 4d60bcb
Author: Cathy Sarisky <[email protected]>
Date:   Sun Oct 27 16:52:37 2024 -0400

    initial commit iwth date error
@cathysarisky cathysarisky changed the title fresh start on theme i18n [WIP, but without 50 bonus commits] [WIP] Theme i18n Oct 31, 2024
Copy link
Contributor

Thanks for contributing to Ghost's i18n :)

This PR has been automatically marked as stale because there has not been any activity here in 3 weeks.
I18n PRs tend to get out of date quickly, so we're closing them to keep the PR list clean.

If you're still interested in working on this PR, please let us know. Otherwise this PR will be closed shortly, but can always be reopened later. Thank you for understanding 🙂

@github-actions github-actions bot added the stale [triage] Issues that were closed to to lack of traction label Apr 29, 2025
Copy link
Contributor

coderabbitai bot commented Apr 29, 2025

Walkthrough

This set of changes refactors the internationalization (i18n) system for theme translations in the codebase. The previous I18n class, which handled loading, managing, and formatting localized strings, has been removed. The ThemeI18n class is re-implemented as a standalone class that no longer inherits from I18n, and now relies directly on the @tryghost/i18n library for translation logic. Its initialization is now asynchronous and requires a theme path, with improved fallback mechanisms for missing or invalid locale files. The translation helper (t) is updated to ensure it always returns a plain string, with explanatory comments added. Test suites for both the helper and the theme i18n service are updated to accommodate asynchronous initialization and to test the new fallback and translation behaviors. The i18n core module is extended to support a new 'theme' namespace, with resource loading from theme directories and namespace-specific interpolation and escaping settings. Comprehensive new tests are added for the i18n module, especially for theme resource loading and configuration.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e95074d and 45666b8.

📒 Files selected for processing (1)
  • ghost/core/core/frontend/helpers/t.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ghost/core/core/frontend/helpers/t.js
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Ghost-CLI tests
  • GitHub Check: Unit tests (Node 22.13.1)
  • GitHub Check: Regression tests (Node 20.11.1, sqlite3)
  • GitHub Check: Unit tests (Node 20.11.1)
  • GitHub Check: Database tests (Node 20.11.1, sqlite3)
  • GitHub Check: Regression tests (Node 20.11.1, mysql8)
  • GitHub Check: Database tests (Node 22.13.1, mysql8)
  • GitHub Check: Database tests (Node 20.11.1, mysql8)
  • GitHub Check: i18n
  • GitHub Check: Lint
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ErisDS ErisDS added the feature [triage] New features we're planning or working on label Apr 30, 2025
@cathysarisky cathysarisky removed the stale [triage] Issues that were closed to to lack of traction label May 4, 2025
@cathysarisky cathysarisky marked this pull request as ready for review May 4, 2025 20:33
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
ghost/core/core/frontend/services/theme-engine/i18n/ThemeI18n.js (3)

52-69: Duplicate FS checks – shave one I/O round-trip

fs.pathExists + fs.access hit the disk twice. A single fs.access (or fs.stat) is enough:

-const themePathExists = await fs.pathExists(themeLocalesPath);
-if (!themePathExists) {
+try {
+    await fs.access(themeLocalesPath);
+} catch {
     this._i18n = {t: key => key};
     return;
-}
+}

This reduces latency and potential TOCTOU windows.


71-79: this._locale is retained when falling back to English – clarify intent

Inside the fallback branch you still call
i18nLib(this._locale, 'theme', …), even though you verified only en.json exists. That’s perfectly valid because the library falls back, but a future maintainer might assume the language switched to en. Consider adding a short comment or explicitly passing 'en' for clarity.


94-100: Guard against non-primitive returns from i18next

You coerce result with String(result), which handles objects like {} but silently converts undefined'undefined'. That may leak into rendered templates. Consider returning '' (an empty string) when the key is missing instead:

-const result = this._i18n.t(key, bindings);
-return typeof result === 'string' ? result : String(result);
+const result = this._i18n.t(key, bindings);
+if (typeof result === 'string') {
+    return result;
+}
+// If i18next returns `undefined`, an object, etc.
+return '';
ghost/i18n/test/i18n.test.js (2)

167-178: Use fs.mkdtemp for isolated temp dirs

All tests share the hard-coded directory temp-theme-locales. If tests run in parallel (e.g. with mocha --parallel) they’ll stomp on each other. Prefer an OS-generated unique directory:

-beforeEach(async function () {
-    themeLocalesPath = path.join(__dirname, 'temp-theme-locales');
-    await fsExtra.ensureDir(themeLocalesPath);
+beforeEach(async function () {
+    themeLocalesPath = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'ghost-theme-i18n-'));

Remember to require('os') at the top.


218-226: Invalid-JSON test may produce unhandled rejection noise

fsExtra.writeFile(..., 'invalid json') causes i18nLib to log a parse error to stderr in some environments, which can clutter CI output. Consider writing an incomplete but valid JSON instead (e.g. '{') or stub the logger to keep test output clean.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc0c405 and e95074d.

📒 Files selected for processing (8)
  • ghost/core/core/frontend/helpers/t.js (1 hunks)
  • ghost/core/core/frontend/services/theme-engine/i18n/I18n.js (0 hunks)
  • ghost/core/core/frontend/services/theme-engine/i18n/ThemeI18n.js (1 hunks)
  • ghost/core/test/unit/frontend/helpers/t.test.js (5 hunks)
  • ghost/core/test/unit/frontend/services/theme-engine/i18n.test.js (1 hunks)
  • ghost/core/test/unit/frontend/services/theme-engine/theme-i18n.test.js (0 hunks)
  • ghost/i18n/lib/i18n.js (3 hunks)
  • ghost/i18n/test/i18n.test.js (2 hunks)
💤 Files with no reviewable changes (2)
  • ghost/core/test/unit/frontend/services/theme-engine/theme-i18n.test.js
  • ghost/core/core/frontend/services/theme-engine/i18n/I18n.js
🧰 Additional context used
🧬 Code Graph Analysis (1)
ghost/i18n/lib/i18n.js (1)
ghost/i18n/test/i18n.test.js (4)
  • fs (2-2)
  • path (3-3)
  • resources (157-157)
  • resources (243-243)
🔇 Additional comments (13)
ghost/i18n/lib/i18n.js (5)

2-3: Good addition of file system dependencies.

These imports are necessary for the new file operations to load theme locale files. Using fs-extra instead of the native fs module is appropriate as it provides additional utilities that simplify file operations.


90-93: Well-documented API changes.

The JSDoc has been properly updated to include the new 'theme' namespace and the options parameter with themePath. This is good practice for maintaining clear API documentation.


94-94: Function signature updated correctly.

The function signature now includes an options parameter with a sensible default empty object, which is consistent with the updated JSDoc.


96-112: Well-structured interpolation and escaping configuration.

The code elegantly configures interpolation delimiters and HTML escaping based on the namespace. For 'theme' and 'newsletter', it uses single curly braces '{' and '}', and specifically for 'theme', it disables HTML escaping. The configuration is clear and includes helpful comments explaining these choices.


161-166: Clear documentation for fallback behavior.

These comments provide excellent explanations of the fallback behavior, clearly documenting how empty strings are handled and which languages are used as fallbacks. This level of documentation is important for future maintenance.

ghost/core/core/frontend/helpers/t.js (1)

29-33: Improved code clarity with explicit result handling.

The code now explicitly stores the result in a variable before returning it, with clear comments explaining that the helper returns a plain string rather than a SafeString. This makes the behavior more explicit and easier to understand.

ghost/core/test/unit/frontend/helpers/t.test.js (2)

17-20: Good test isolation practice.

Adding a beforeEach hook to reset the internal _i18n instance before each test ensures proper test isolation and prevents test state from bleeding between tests.


22-30: Properly updated tests for async initialization.

The tests have been correctly converted to async functions to properly await the asynchronous themeI18n.init calls. This change is necessary to support the new asynchronous initialization pattern and was applied consistently across all tests.

Also applies to: 32-40, 42-50, 52-60, 78-84

ghost/core/test/unit/frontend/services/theme-engine/i18n.test.js (5)

3-4: Correctly updated imports for new implementation.

The imports have been updated to reflect the change from the old I18n class to the new ThemeI18n class, and the addition of the path module for path operations is appropriate for the implementation.


6-16: Well-structured test setup.

The test suite has been updated to properly test the ThemeI18n class with a good setup that creates a clean instance before each test and uses appropriate fixtures. The use of sinon.restore() in afterEach ensures proper cleanup.


18-26: Comprehensive locale handling tests.

These tests effectively verify that the default locale is "en" and that different locales can be set during initialization. The second test is properly marked as async to handle the asynchronous init call.


27-31: Good initialization test with real translations.

This test verifies that the class can be initialized with a theme path and that translations work correctly. Using real theme fixtures with actual translation files makes this test more robust.


33-61: Comprehensive testing of translation behaviors.

These tests thoroughly verify various aspects of translation behavior, including:

  • Fallback to English when translations aren't found
  • Fallback to the key itself when no translation files exist
  • Empty key handling
  • Error handling for use before initialization
  • Key fallback for unknown strings

This level of test coverage is excellent for ensuring the reliability of the refactored implementation.

Comment on lines +114 to +151
let resources;
if (ns !== 'theme') {
resources = generateResources(SUPPORTED_LOCALES, ns);
} else {
// For theme namespace, we need to load translations from the theme's locales directory
resources = {};
const themeLocalesPath = options.themePath;

if (themeLocalesPath) {
// Try to load the requested locale first
try {
const localePath = path.join(themeLocalesPath, `${lng}.json`);
const content = fs.readFileSync(localePath, 'utf8');
resources[lng] = {
theme: JSON.parse(content)
};
} catch (err) {
// If the requested locale fails, try English as fallback
try {
const enPath = path.join(themeLocalesPath, 'en.json');
const content = fs.readFileSync(enPath, 'utf8');
resources[lng] = {
theme: JSON.parse(content)
};
} catch (enErr) {
// If both fail, use an empty object
resources[lng] = {
theme: {}
};
}
}
} else {
// If no theme path provided, use empty translations
resources[lng] = {
theme: {}
};
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using asynchronous file operations for theme resource loading.

While the resource loading logic for the 'theme' namespace is well-structured and includes clear fallback mechanisms, it uses synchronous file reading (fs.readFileSync), which could block the event loop in a production environment.

- const content = fs.readFileSync(localePath, 'utf8');
+ // Use fs-extra's readFile which returns a promise
+ const content = await fs.readFile(localePath, 'utf8');

Additionally, consider simplifying the nested error handling structure to make the code more maintainable.

Committable suggestion skipped: line range outside the PR's diff.

revert unnecessary change in t.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects:i18n feature [triage] New features we're planning or working on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants