Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
bfc9d66
Customize picked relationship item
s3rgiosan Apr 4, 2025
93eae18
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan May 16, 2025
2311f6b
Replace Truncate component with Text component and add title attribut…
s3rgiosan May 16, 2025
9544833
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan May 22, 2025
4d1845f
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 12, 2026
58bccc9
Add filters to customize the search result and the picked item
s3rgiosan Jan 12, 2026
dc8a226
Add container to allow for customization
s3rgiosan Jan 12, 2026
812a473
Update built assets
s3rgiosan Jan 12, 2026
017c37f
Add filter to customize the picked item preview component
s3rgiosan Jan 12, 2026
d409b64
Remove script localization
s3rgiosan Jan 12, 2026
2afbfef
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
116792b
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
964ce06
Fix hook dependencies
s3rgiosan Jan 30, 2026
2a6c0f3
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
f87a51b
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
7c508d9
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
a98d959
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
02d40bc
Merge branch 'feature/data-api-backbone' into feature/picked-relation…
s3rgiosan Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
242 changes: 238 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,17 @@ For example, this is fine:
```

while this will not work (orderby will be ignored):

```php
'relationship_query' => array(
array(
'related_to_post' => 25,
'name' => 'related',
),
array(
'related_to_post' => 15,
'name' => 'related',
),
'related_to_post' => 15,
'name' => 'related',
),
),
'orderby' => 'relationship',
```
Expand Down Expand Up @@ -474,6 +475,240 @@ User ID 1 has 5 posts that need to be stored in the following order: 4, 2, 7, 9,
$relationship->save_user_to_post_sort_data( 1, array( 4, 2, 7, 9, 8 ) );
```

## Customizing the Block Editor UI

Content Connect provides WordPress JavaScript filters that allow you to customize the search results and picked items display in the Block Editor. These filters are context-aware and receive relationship information, enabling both global and per-relationship customization.

### Available Filters

#### `contentConnect.searchResultFilter`

Customizes how search results are displayed in the ContentPicker component. This filter receives the default filter function and a context object containing relationship information.

**Filter:**

```javascript
addFilter(
'contentConnect.searchResultFilter',
'your-plugin/namespace',
(defaultFilter, context) => {
// Return a custom filter function
}
);
```

**Context Object:**

```typescript
{
rel_key: string; // The relationship key
rel_type: string; // 'post-to-post' or 'post-to-user'
postId: number | null; // Current post ID
mode: 'post' | 'user'; // Content search mode
}
```

#### `contentConnect.pickedItemFilter`

Customizes how picked items are displayed in the ContentPicker component list. This filter receives the default filter function and a context object containing relationship information.

**Filter:**

```javascript
addFilter(
'contentConnect.pickedItemFilter',
'your-plugin/namespace',
(defaultFilter, context) => {
// Return a custom filter function
}
);
```

#### `contentConnect.pickedItemPreviewComponent`

Customizes the React component used to render picked items in the ContentPicker component list. This filter receives the default filter and a context object containing relationship information.

**Filter:**

```javascript
addFilter(
'contentConnect.pickedItemPreviewComponent',
'your-plugin/namespace',
(defaultComponent, context) => {
// Return a custom React component
}
);
```

### Usage Examples

#### Global Customization

Apply the same customization to all relationships:

```javascript
import { addFilter } from '@wordpress/hooks';

addFilter(
'contentConnect.searchResultFilter',
'my-project/customize-search-results',
(defaultFilter, context) => {
return (item, result) => {
return {
...item,
url: '',
info: `<strong>ID:</strong> ${result.id}`,
};
};
}
);

addFilter(
'contentConnect.pickedItemFilter',
'my-project/customize-picked-items',
(defaultFilter, context) => {
return (item, result) => {
return {
...item,
url: '',
info: `<strong>ID:</strong> ${result.id}`,
};
};
}
);
```

#### Per-Relationship Customization

Customize behavior based on the relationship key or type:

```javascript
import { addFilter } from '@wordpress/hooks';

addFilter(
'contentConnect.searchResultFilter',
'my-project/customize-specific-relationship',
(defaultFilter, context) => {
// Only customize for a specific relationship
if (context.rel_key === 'my-specific-relationship') {
return (item, result) => {
return {
...item,
url: '',
info: `<strong>Special:</strong> ${result.id}`,
};
};
}
// Return default for other relationships
return defaultFilter;
}
);

addFilter(
'contentConnect.pickedItemFilter',
'my-project/customize-picked-items-by-type',
(defaultFilter, context) => {
// Customize based on relationship type
if (context.rel_type === 'post-to-user') {
return (item, result) => {
return {
...item,
url: '',
info: `User: ${result.name || result.username}`,
};
};
}
return defaultFilter;
}
);
```

#### Accessing Additional REST API Fields

To display additional fields from the REST API, you may need to register them first in PHP:

```php
add_action('rest_api_init', function() {
register_rest_field('search-result', 'excerpt', array(
'get_callback' => function($post) {
return get_the_excerpt($post['id']);
},
'update_callback' => null,
'schema' => null,
));
});
```

Then use them in your filter:

```javascript
addFilter(
'contentConnect.searchResultFilter',
'my-project/add-excerpt',
(defaultFilter, context) => {
return (item, result) => {
// result.excerpt is a string from the REST API search endpoint
return {
...item,
url: '',
info: `<strong>ID:</strong> ${result.id}<br>${result.excerpt || ''}`,
};
};
}
);

addFilter(
'contentConnect.pickedItemFilter',
'my-project/add-excerpt-to-picked',
(defaultFilter, context) => {
return (item, result) => {
// result.excerpt.rendered is from getEntityRecord (core WordPress entity)
return {
...item,
url: '',
info: `<strong>ID:</strong> ${result.id}<br>${result.excerpt?.rendered || ''}`,
};
};
}
);
```

#### Custom Preview Component

Customize the React component used to render picked items:

```javascript
import { addFilter } from '@wordpress/hooks';
import { __experimentalText as Text } from '@wordpress/components';
import { decodeEntities } from '@wordpress/html-entities';

addFilter(
'contentConnect.pickedItemPreviewComponent',
'my-project/custom-preview',
(defaultComponent, context) => {
return ({ item }) => {
const decodedTitle = decodeEntities(item.title);
return (
<Text
truncate={false}
title={decodedTitle}
aria-label={decodedTitle}
>
{decodedTitle}
</Text>
);
};
}
);
```

### Best Practices

1. **Return Plain Functions**: Filter callbacks should return plain functions, not React hooks. The component handles memoization internally. For `pickedItemPreviewComponent`, return a React component function.
2. **Check Context**: Use the context object to conditionally apply customizations based on relationship key, type, or post ID
3. **Return Default When Appropriate**: If your filter doesn't apply to a specific context, return the `defaultFilter` or `defaultComponent` to maintain default behavior
4. **Type Safety**: Use TypeScript types when available to ensure type safety

## Support Level

**Stable:** 10up is not planning to develop any new features for this, but will still respond to bug reports and security concerns. We welcome PRs, but any that include new features should be small and easy to integrate and should not include breaking changes. We otherwise intend to keep this tested up to the most recent version of WordPress.
Expand All @@ -486,7 +721,6 @@ A complete listing of all notable changes to WP Content Connect are documented i

Please read [CODE_OF_CONDUCT.md](https://github.com/10up/wp-content-connect/blob/develop/CODE_OF_CONDUCT.md) for details on our code of conduct, [CONTRIBUTING.md](https://github.com/10up/wp-content-connect/blob/develop/CONTRIBUTING.md) for details on the process for submitting pull requests to us, and [CREDITS.md](https://github.com/10up/wp-content-connect/blob/develop/CREDITS.md) for a listing of maintainers of, contributors to, and libraries used by WP Content Connect.


## Like what you see?

<p align="center">
Expand Down
Loading