diff --git a/.changeset/odd-tigers-cover.md b/.changeset/odd-tigers-cover.md new file mode 100644 index 000000000..eab43c623 --- /dev/null +++ b/.changeset/odd-tigers-cover.md @@ -0,0 +1,35 @@ +--- +'@faustwp/core': patch +--- + +Adds new hook wpAdminUrl that lets user customize the wp-admin url in toolbar + +Usage: + +```js +export class MyPlugin { + apply(hooks) { + const { addAction, addFilter } = hooks; + + addFilter( + 'wpAdminUrl', + 'my-namespace', + (wpAdminUrl, context) => { + // replaces default wp-admin url at /wp-admin with /wp/wp-admin + return wpAdminUrl.replace('/wp-admin', '/wp/wp-admin') + }, + ); + } +} + +/** + * @type {import('@faustwp/core').FaustConfig} + **/ +export default setConfig({ + templates, + plugins: [new MyPlugin()], + experimentalToolbar: true, + possibleTypes, +}); + +``` diff --git a/packages/faustwp-core/src/lib/getAdminUrl.ts b/packages/faustwp-core/src/lib/getAdminUrl.ts index 974c11f08..17568436f 100644 --- a/packages/faustwp-core/src/lib/getAdminUrl.ts +++ b/packages/faustwp-core/src/lib/getAdminUrl.ts @@ -1,4 +1,5 @@ import { getWpUrl } from './getWpUrl.js'; +import { hooks } from '../wpHooks/index.js'; /** * Retrieves the URL to the admin area for the current site. @@ -8,7 +9,9 @@ import { getWpUrl } from './getWpUrl.js'; * @param {string} path Path relative to the admin URL. */ export function getAdminUrl(path = ''): string { - const adminUrl = getWpUrl('wp-admin'); + let adminUrl = getWpUrl('wp-admin'); + + adminUrl = hooks.applyFilters('wpAdminUrl', adminUrl, {}) as string; if (!path) { return adminUrl; diff --git a/packages/faustwp-core/src/wpHooks/overloads.ts b/packages/faustwp-core/src/wpHooks/overloads.ts index 74bddbeda..de41fc080 100644 --- a/packages/faustwp-core/src/wpHooks/overloads.ts +++ b/packages/faustwp-core/src/wpHooks/overloads.ts @@ -71,6 +71,13 @@ type FaustCoreFilters = { priority?: number | undefined, ): void; + addFilter( + hookName: 'wpAdminUrl', + namespace: string, + callback: (wpAdminUrl: string, context: Record) => string, + priority?: number | undefined, + ): void; + addFilter( hookName: 'toolbarNodes', namespace: string, diff --git a/packages/faustwp-core/tests/lib/getAdminUrl.test.ts b/packages/faustwp-core/tests/lib/getAdminUrl.test.ts new file mode 100644 index 000000000..e6dd05e16 --- /dev/null +++ b/packages/faustwp-core/tests/lib/getAdminUrl.test.ts @@ -0,0 +1,50 @@ +import { createHooks } from '@wordpress/hooks'; +import { hooks } from '../../src/wpHooks/index'; +import { getAdminUrl } from '../../src/lib/getAdminUrl'; +import { getWpUrl } from '../../src/lib/getWpUrl'; + +jest.mock('@wordpress/hooks', () => ({ + createHooks: jest.fn().mockReturnValue({ + applyFilters: jest.fn(), + }), +})); + +jest.mock('../../src/lib/getWpUrl', () => ({ + getWpUrl: jest.fn().mockReturnValue('http://example.com/wp-admin'), +})); + +describe('getAdminUrl', () => { + beforeEach(() => { + hooks.actions = Object.create( null ); + hooks.filters = Object.create( null ); + (createHooks().applyFilters as jest.Mock).mockClear(); + (getWpUrl as jest.Mock).mockClear(); + }); + + it('returns the admin URL without path when no path is provided', () => { + const mockUrl = 'http://example.com/wp-admin'; + (createHooks().applyFilters as jest.Mock).mockReturnValue(mockUrl); + + const result = getAdminUrl(); + expect(result).toBe(mockUrl); + expect(createHooks().applyFilters).toHaveBeenCalledWith( + 'wpAdminUrl', + mockUrl, + {}, + ); + }); + + it('returns the admin URL with path when path is provided', () => { + const mockUrl = 'http://example.com/wp-admin'; + const path = 'test-path'; + (createHooks().applyFilters as jest.Mock).mockReturnValue(mockUrl); + + const result = getAdminUrl(path); + expect(result).toBe(`${mockUrl}/${path}`); + expect(createHooks().applyFilters).toHaveBeenCalledWith( + 'wpAdminUrl', + mockUrl, + {}, + ); + }); +});