Cross Content
Enable the following module:
vactory_cross_content
Visit :
/admin/structure/types/manage/**content_type**
Enable the cross content.
Move to the Block Layout page.
Inject the cross content block. Ensure that you select the one with the vactory category.
Visit
/block/add/vactory_block_component
Create your custom cross content block, ensure that you have already created a dynamic field that will be displayed on the Next.js app to show your cross content items.
Here's a simple example :
./modules/custom/your_custom_module/widgets/cross-content-news/settings.yml
name: 'Cross content news'multiple: FALSEcategory: 'Cross Content'enabled: TRUEfields: title: type: text label: "title" intro: type: text_format label: "Introduction" options: "#format": full_html link: type: url_extended label: "Link"
Inject your cross-content custom block into the Footer region and ensure that you have configured the Visibility settings.
On Next.js, you will need to create a mapping file.
./components/modules/news/CrossContentWidget.jsx
export const config = { id: "vactory_news:cross-content-news",}
const CrossContentNews = ({ data }) => { console.log({data}) return <>News Cross Content</>}
export default CrossContentNews
./components/modules/news/NewsNode.jsx
export const config = { id: "node--vactory_news", params: { fields: { "node--vactory_news": "vcc_normalized,title,body,field_vactory_excerpt,field_vactory_media,field_vactory_date", "media--image": "thumbnail", "file--image": "uri", }, include: "field_vactory_media,field_vactory_media.thumbnail", },}
Now that we have included vcc_normalized
to be retrieved along with the node fields data,
the remaining step is to get the cross-content items from the node context.
For this we need to use the useNode
custom hook.
You need to import the useNode from the hooks package.
./components/modules/news/CrossContentWidget.jsx
import { useNode } from "@vactorynext/core/hooks"
Congratulations! You have just displayed the cross content!
./components/modules/news/CrossContentWidget.jsx
import { useNode } from "@vactorynext/core/hooks"
export const config = { id: "vactory_news:cross-content-news",}
const CrossContentNews = ({ data }) => { const { vcc } = useNode() console.log({vcc})
return <> {vcc?.map((item) => item?.title)} </>}
export default CrossContentNews
If you want to display additional information such as images, dates, or other details, what steps should you take ?
To address this problem, a new hook is implemented on the Drupal side called hook_jsonapi_vcc_normalized_node_alter(&$normalized_node, $context, $base_node_type)
.
This hook allows developers to append additional information to vcc_normalized
field.
Here's an example :
./modules/custom/your_custom_module/your_custom_module.module
function your_custom_module_jsonapi_vcc_normalized_node_alter(&$normalized_node, $context, $base_node_type) { if ($base_node_type === 'vactory_news') { $node = $context['node']; $node_type = $context['node_type']; if ($node_type === 'vactory_news') { // Get image. $lqipImageStyle = ImageStyle::load('lqip'); $output_field_name = 'field_vactory_media'; $mid = $node->get($output_field_name)->getString(); $result[$output_field_name] = NULL; if (!empty($mid)) { $mid = (int) $mid; $media = Media::load($mid); if ( $media && $media->bundle() === 'image' && isset($media->get('field_media_image')->getValue()[0]['target_id']) ) { $fid = $media->get('field_media_image')->getValue()[0]['target_id']; $file = File::load($fid); if ($file != NULL) { $uri = $file->getFileUri(); $fileResult = []; $media_file_manager = \Drupal::service('vacory_decoupled.media_file_manager'); $fileResult['_default'] = $media_file_manager->getMediaAbsoluteUrl($uri); $fileResult['_lqip'] = $media_file_manager->convertToMediaAbsoluteUrl($lqipImageStyle->buildUrl($uri)); $fileResult['uri'] = StreamWrapperManager::getTarget($uri); $fileResult['fid'] = $fid; $fileResult['file_name'] = $media->label(); $fileResult['meta'] = $media->get('field_media_image') ->first() ->getValue(); $result[$output_field_name] = $fileResult; } }
}
$normalized_node = [ 'id' => $node->id(), 'image' => $result[$output_field_name], 'title' => $node->label(), 'excerpt' => $node->get('field_vactory_excerpt')->getValue(), 'url' => $node->toUrl()->toString(), ];
} }}