Since version 1.5, AQL is now completely extendable. Using the SlotFills and filter outlined below, you can add any custom control you may need! The code below can be seen in my advanced-query-loop-extension plugin here
There are two SlotFills available to extend the UI of AQL that are exposed based the value of the Inherit query from template
setting of the block.
The purpose of having two options is to be able to customize when a UI element is added. There may be cases that a particular control doesn't make sense to be shown when the query is being inherited.
For example, a control that makes changes to the content types being displayed may not make sense when used in an archive template and so that control would only be added using the <AQLControls
SlotFill so that it doesn't appear when Inherit query from template
is enabled.
- AQLControls
- AQLControlsInheritedQuery
Both SlotFills are passed all props
from the main block and are available on the window.aql
object for use.
The example below adds a new control to only show content from the from currently logged in user regardless of the status of Inherit query from template
.
const { AQLControls, AQLControlsInheritedQuery } = window.aql;
import { registerPlugin } from '@wordpress/plugins';
import { ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
const LoggedInUserControl = ( { attributes, setAttributes } ) => {
const { query: { authorContent = false } = {} } = attributes;
return (
<>
<ToggleControl
label={ __( 'Show content for logged in user only' ) }
checked={ authorContent === true }
onChange={ () => {
setAttributes( {
query: {
...attributes.query,
authorContent: ! authorContent,
},
} );
} }
/>
</>
);
};
registerPlugin( 'aql-extension', {
render: () => {
return (
<>
<AQLControls>
{ ( props ) => <LoggedInUserControl { ...props } /> }
</AQLControls>
<AQLControlsInheritedQuery>
{ ( props ) => <LoggedInUserControl { ...props } /> }
</AQLControlsInheritedQuery>
</>
);
},
} );
Once the control is in place and saving, you will need to use that new query variable to modify the underlying WP_Query
instance via the aql_query_vars
filter.
The filter provides three parameters:
$query_args
Arguments to be passed to WP_Query.$block_query
The query attribute retrieved from the block.$inherited
Whether the query is being inherited.
The example code below modifies the query based on the status of the control added above.
/**
* Add a filter to only show logged-in user content.
*
* @param array $query_args Arguments to be passed to WP_Query.
* @param array $block_query The query attribute retrieved from the block.
* @param boolean $inherited Whether the query is being inherited.
*/
function aql_extension_show_current_author_only( $query_args, $block_query, $inherited ) {
if (
isset( $block_query['authorContent'] ) &&
true === filter_var( $block_query['authorContent'], FILTER_VALIDATE_BOOLEAN )
) {
$query_args['author'] = get_current_user_id();
}
return $query_args;
}
\add_filter( 'aql_query_vars', 'aql_extension_show_current_author_only', 10, 3 );
Using he example code above, you can make a custom extension plugin for AQL that will filter the displayed posts by author.
Start by using the @wordpress/create-block
package to scaffold all of the files we need. We will be removing all of the block-related ones but this tool can quickly get us set up and ready to go.
The the following in the command line tool of your choice inside the wp-content folder of a local WordPress installation.
npx @wordpress/create-block custom-aql-extension
Once the scaffold has been completed, delete all of the files in custom-aql-extension/src
we don't need them.
Create a new files calledwebpack.config.js
in the root of the directory with with the following contents:
// Import the original config from the @wordpress/scripts package.
const defaultConfig = require("@wordpress/scripts/config/webpack.config");
// Add any a new entry point by extending the webpack config.
module.exports = {
...defaultConfig,
entry: {
`aql-extension`: './src/index.js
},
};
Create an index.js
file inside of the ./src
directory with the following contents:
const { AQLControls, AQLControlsInheritedQuery } = window.aql;
import { registerPlugin } from '@wordpress/plugins';
import { ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
const LoggedInUserControl = ( { attributes, setAttributes } ) => {
const { query: { authorContent = false } = {} } = attributes;
return (
<>
<ToggleControl
label={ __( 'Show content for logged in user only' ) }
checked={ authorContent === true }
onChange={ () => {
setAttributes( {
query: {
...attributes.query,
authorContent: ! authorContent,
},
} );
} }
/>
</>
);
};
registerPlugin( 'aql-extension', {
render: () => {
return (
<>
<AQLControls>
{ ( props ) => <LoggedInUserControl { ...props } /> }
</AQLControls>
<AQLControlsInheritedQuery>
{ ( props ) => <LoggedInUserControl { ...props } /> }
</AQLControlsInheritedQuery>
</>
);
},
} );
Next open the scaffolded index.php
file in the root directory and remove the existing code ( be sure to leave the header comments) and add the following to enqueue the JavaScript file.
\add_action(
'enqueue_block_editor_assets',
function () {
$extension_assets_file = plugin_dir_path( __FILE__ ) . 'build/aql-extension.asset.php';
if ( file_exists( $extension_assets_file ) ) {
$assets = include $extension_assets_file;
\wp_enqueue_script(
'aql-extension',
plugin_dir_url( __FILE__ ). 'build/aql-extension.js',
$assets['dependencies'],
$assets['version'],
true
);
}
}
);
Next, add the following hooks to filter AQL
/**
* Add a filter to only show logged-in user content.
*
* @param array $query_args Arguments to be passed to WP_Query.
* @param array $block_query The query attribute retrieved from the block.
* @param boolean $inherited Whether the query is being inherited.
*/
function aql_extension_show_current_author_only( $query_args, $block_query, $inherited ) {
if (
isset( $block_query['authorContent'] ) &&
true === filter_var( $block_query['authorContent'], FILTER_VALIDATE_BOOLEAN )
) {
$query_args['author'] = get_current_user_id();
}
return $query_args;
}
\add_filter( 'aql_query_vars', 'aql_extension_show_current_author_only', 10, 3 );
Now that all the code is in place, back in your terminal run the one of the following commands:
npm run start
- starts development mode for the plugin that will rebuild when things changenpm run build
- creates a production build of the plugin
Before you can use the plugin you need to run of the two
Enable the plugin in your local WordPress environment