feat: AcfProse

This commit is contained in:
2026-03-30 09:48:28 -04:00
parent 867d0b3e44
commit edb3797f81
7 changed files with 199 additions and 50 deletions

View File

@@ -47,53 +47,6 @@
"acfe_flexible_modal_settings_close_label": ""
},
"layouts": {
"layout_69c67f5b55d71": {
"key": "layout_69c67f5b55d71",
"name": "prose",
"label": "Prose",
"display": "block",
"sub_fields": [
{
"key": "field_69c681a24b946",
"label": "Contenu",
"name": "content",
"aria-label": "",
"type": "wysiwyg",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"allow_in_bindings": 0,
"tabs": "all",
"toolbar": "full",
"media_upload": 1,
"delay": 0,
"show_in_graphql": 1,
"graphql_description": "",
"graphql_field_name": "content",
"graphql_non_null": 0
}
],
"min": "",
"max": "",
"acfe_flexible_modal_edit_size": "",
"acfe_flexible_settings": [
"group_layout_padding",
"group_layout_container",
"group_layout_color"
],
"acfe_flexible_settings_size": "",
"acfe_flexible_render_template": false,
"acfe_flexible_render_style": false,
"acfe_flexible_render_script": false,
"acfe_flexible_thumbnail": false,
"acfe_flexible_category": false
},
"layout_69c69985e74f4": {
"key": "layout_69c69985e74f4",
"name": "template",
@@ -154,6 +107,56 @@
"acfe_flexible_render_script": false,
"acfe_flexible_thumbnail": false,
"acfe_flexible_category": false
},
"layout_69ca7bceae24b": {
"key": "layout_69ca7bceae24b",
"name": "prose",
"label": "Prose",
"display": "block",
"sub_fields": [
{
"key": "field_69ca7bd9ae253",
"label": "Prose",
"name": "prose",
"aria-label": "",
"type": "clone",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"graphql_field_name": "prose",
"clone": [
"group_abstract_prose"
],
"display": "group",
"layout": "block",
"prefix_label": 0,
"prefix_name": 1,
"acfe_seamless_style": 1,
"acfe_clone_modal": 0,
"acfe_clone_modal_close": 0,
"acfe_clone_modal_button": "",
"acfe_clone_modal_size": "large"
}
],
"min": "",
"max": "",
"acfe_flexible_modal_edit_size": "",
"acfe_flexible_settings": [
"group_layout_padding",
"group_layout_container",
"group_layout_color"
],
"acfe_flexible_settings_size": "",
"acfe_flexible_render_template": false,
"acfe_flexible_render_style": false,
"acfe_flexible_render_script": false,
"acfe_flexible_thumbnail": false,
"acfe_flexible_category": false
}
},
"min": "",
@@ -195,5 +198,5 @@
"graphql_types": "",
"acfe_meta": "",
"acfe_note": "",
"modified": 1774874306
"modified": 1774878313
}

View File

@@ -0,0 +1,59 @@
{
"key": "group_abstract_prose",
"title": "Abstract - Prose",
"fields": [
{
"key": "field_69ca7a237541f",
"label": "Contenu",
"name": "content",
"aria-label": "",
"type": "wysiwyg",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"allow_in_bindings": 0,
"tabs": "all",
"toolbar": "full",
"media_upload": 1,
"delay": 0,
"show_in_graphql": 1,
"graphql_description": "",
"graphql_field_name": "content",
"graphql_non_null": 1
}
],
"location": [
[
{
"param": "abstract"
}
]
],
"menu_order": 0,
"position": "acf_after_title",
"style": "seamless",
"label_placement": "top",
"instruction_placement": "label",
"hide_on_screen": "",
"active": true,
"description": "",
"show_in_rest": 0,
"display_title": "",
"acfe_autosync": [
"json"
],
"acfe_form": 0,
"show_in_graphql": 1,
"graphql_field_name": "GroupAbstractProse",
"map_graphql_types_from_location_rules": 0,
"graphql_types": "",
"acfe_meta": "",
"acfe_note": "",
"modified": 1774877376
}

View File

@@ -0,0 +1,3 @@
fragment AcfProse on GroupAbstractProse_Fields {
content
}

View File

@@ -0,0 +1,12 @@
<script setup lang="ts">
import type { AcfProseFragment } from "#graphql/types";
defineProps<{ prose: AcfProseFragment }>();
const refContent = useTemplateRef("refContent");
useProseLinks(refContent);
</script>
<template>
<div ref="refContent" class="prose" v-html="prose.content" />
</template>

View File

@@ -1,5 +1,7 @@
fragment SectionProse on GroupAbstractBuilderSectionsProseLayout {
content
prose @nonNull {
...AcfProse
}
layout: layoutSettings @nonNull {
...AcfLayout
}

View File

@@ -6,6 +6,6 @@ defineProps<{ section: SectionProseFragment }>();
<template>
<AcfLayout :layout="section.layout">
<div class="prose" v-html="section.content"></div>
<AcfProse :prose="section.prose" />
</AcfLayout>
</template>

View File

@@ -0,0 +1,70 @@
export function useProseLinks(refContent: Ref<HTMLElement | null>) {
const router = useRouter();
const { url } = useSiteConfig();
const siteUrl = new URL(url);
// Determine if the href is internal
const isInternal = (href: string) => {
if (!href) return false;
if (href.startsWith("/")) return true;
if (href.startsWith("#")) return false;
try {
const hrefUrl = new URL(href);
return hrefUrl.hostname === siteUrl.hostname;
} catch {
return false;
}
};
// Convert href to relative path
const convertToRelative = (href: string) => {
if (href.startsWith("/")) return href;
try {
const hrefUrl = new URL(href);
if (hrefUrl.hostname === siteUrl.hostname) {
return hrefUrl.pathname + hrefUrl.search + hrefUrl.hash;
}
} catch {
// Invalid URL
}
return href;
};
// Highjack click events to use router for internal links
const handleClick = (event: MouseEvent) => {
const target = event.target as HTMLElement;
const link = target.closest("a");
if (!link) return;
const href = link.getAttribute("href");
if (!href) return;
if (
event.metaKey ||
event.ctrlKey ||
event.shiftKey ||
event.altKey ||
link.target === "_blank" ||
link.hasAttribute("download")
) {
return;
}
if (isInternal(href)) {
event.preventDefault();
const path = convertToRelative(href);
router.push(path);
}
};
// Attach and detach event listeners
onMounted(() => {
const element = unref(refContent);
if (element) {
element.addEventListener("click", handleClick);
}
});
onBeforeUnmount(() => {
const element = unref(refContent);
if (element) {
element.removeEventListener("click", handleClick);
}
});
}