Skip to content

Commit

Permalink
Merge pull request #10 from wp-graphql/issue-4-hooks
Browse files Browse the repository at this point in the history
First pass at creating a more extensible plugin
  • Loading branch information
josephfusco authored Feb 23, 2024
2 parents 9b99405 + a0e836f commit 7111f06
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 20 deletions.
24 changes: 24 additions & 0 deletions ACTIONS_AND_FILTERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Actions & Filters

-> [Original documentation](https://www.wpgraphql.com/docs/customizing-wpgraphiql)

_legend_ 🎉 = new

## PHP Actions

- `wpgraphqlide_enqueue_script` ([enqueue_graphiql_extension](https://www.wpgraphql.com/docs/customizing-wpgraphiql#enqueue_graphiql_extension))

## PHP Filters

- `wpgraphqlide_capability_required` 🎉
- `wpgraphqlide_context` 🎉
- `wpgraphqlide_external_fragments` ([graphiql_external_fragments](https://www.wpgraphql.com/docs/customizing-wpgraphiql#graphiql_external_fragments))

## JavaScript Actions

- `wpgraphqlide_destroyed` 🎉
- `wpgraphqlide_rendered` ([graphiql_rendered](https://www.wpgraphql.com/docs/customizing-wpgraphiql#graphiql_rendered))

## JavaScript Filters

...
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ GraphiQL IDE has intentionally been updated to read "GraphQL IDE", which feels m
```

Builds are only required for JS updates as the plugin's CSS is directly enqueued.
## Custom Hooks
See [ACTIONS_AND_FILTERS.md].
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"dependencies": {
"@wordpress/element": "^5.23.0",
"@wordpress/hooks": "^3.49.0",
"graphiql": "^3.0.10",
"graphql-ws": "^5.14.2",
"vaul": "^0.7.9"
Expand Down
50 changes: 40 additions & 10 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,45 @@
import { useState } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';
import { EditorDrawer } from './components/EditorDrawer';
import { Editor } from './components/Editor';

// Assuming wp.hooks is globally available through WordPress's script enqueueing mechanism.
const { doAction } = wp.hooks;

/**
* The main application component.
*
* @returns {JSX.Element} The application component.
*/
export function App() {
const [ drawerOpen, setDrawerOpen ] = useState( false );

return (
<div className="AppRoot">
<EditorDrawer open={ drawerOpen } setDrawerOpen={ setDrawerOpen }>
<Editor setDrawerOpen={ setDrawerOpen } />
</EditorDrawer>
</div>
);
const [drawerOpen, setDrawerOpen] = useState(false);

useEffect(() => {
/**
* Perform actions on component mount.
*
* Triggers a custom action 'wpgraphqlide_rendered' when the App component mounts,
* allowing plugins or themes to hook into this event. The action passes
* the current state of `drawerOpen` to any listeners, providing context
* about the application's UI state.
*/
doAction('wpgraphqlide_rendered', drawerOpen);

/**
* Cleanup action on component unmount.
*
* Returns a cleanup function that triggers the 'wpgraphqlide_destroyed' action,
* signaling that the App component is about to unmount. This allows for
* any necessary cleanup or teardown operations in response to the App
* component's lifecycle.
*/
return () => doAction('wpgraphqlide_destroyed');
}, [drawerOpen]);

return (
<div className="AppRoot">
<EditorDrawer open={ drawerOpen } setDrawerOpen={ setDrawerOpen }>
<Editor setDrawerOpen={setDrawerOpen} />
</EditorDrawer>
</div>
);
}
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* global WPGRAPHQL_IDE_DATA */
import { createRoot } from '@wordpress/element';
import { createHooks } from '@wordpress/hooks';

import { App } from './App';

/**
Expand All @@ -18,5 +20,8 @@ if ( rootElement ) {
root.render( <App /> );
}

// Initialize hook system.
App.hooks = createHooks();

// Expose app as a global variable to utilize in gutenberg.
window.WPGraphQLIDE = App;
38 changes: 32 additions & 6 deletions wpgraphql-ide.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ function enqueue_react_app_with_styles(): void {
'wp-i18n',
];

$version = plugin_version();
$app_context = get_app_context();

$version = get_plugin_header( 'Version' );

wp_enqueue_script(
'wpgraphql-ide-app',
Expand All @@ -138,28 +140,52 @@ function enqueue_react_app_with_styles(): void {
'nonce' => wp_create_nonce( 'wp_rest' ),
'graphqlEndpoint' => trailingslashit( site_url() ) . 'index.php?' . \WPGraphQL\Router::$route,
'rootElementId' => WPGRAPHQL_IDE_ROOT_ELEMENT_ID,
'context' => $app_context,
]
);

wp_enqueue_style( 'wpgraphql-ide-app', plugins_url( 'build/index.css', __FILE__ ), [], $version );
// Avoid running custom styles through a build process for an improved developer experience.
wp_enqueue_style( 'wpgraphql-ide', plugins_url( 'styles/wpgraphql-ide.css', __FILE__ ), [], $version );

// Extensions looking to extend GraphiQL can hook in here,
// after the window object is established, but before the App renders
do_action( 'wpgraphqlide_enqueue_script', $app_context );
}
add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\\enqueue_react_app_with_styles' );
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\enqueue_react_app_with_styles' );

/**
* Retrieves the version of the current plugin.
* Retrieves the specific header of this plugin.
*
* @return string The version number of the plugin. Returns an empty string if the version is not found.
* @param string The plugin data key.
* @return string|null The version number of the plugin. Returns an empty string if the version is not found.
*/
function plugin_version(): string {
function get_plugin_header( $key = '' ): ?string {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}

if ( empty( $key ) ) {
return null;
}

$plugin_data = get_plugin_data( __FILE__ );
$version = $plugin_data['Version'];

return $version;
return $plugin_data[ $key ] ?? null;
}

/**
* Retrieves app context.
*
* @return array The possibly filtered app context array.
*/
function get_app_context() {
$context = apply_filters( 'wpgraphqlide_context', [
'pluginVersion' => get_plugin_header( 'Version' ),
'pluginName' => get_plugin_header( 'Name' ),
'externalFragments' => apply_filters( 'wpgraphqlide_external_fragments', [] )
]);

return $context;
}

0 comments on commit 7111f06

Please sign in to comment.