From edb3797f81e12295bb60e6b6f1cd29e37b79d424 Mon Sep 17 00:00:00 2001 From: Pascal Martineau Date: Mon, 30 Mar 2026 09:48:28 -0400 Subject: [PATCH] feat: AcfProse --- .../acf-json/group_abstract_builder.json | 99 ++++++++++--------- .../acf-json/group_abstract_prose.json | 59 +++++++++++ .../headless/app/components/acf/AcfProse.gql | 3 + .../headless/app/components/acf/AcfProse.vue | 12 +++ .../app/components/sections/SectionProse.gql | 4 +- .../app/components/sections/SectionProse.vue | 2 +- .../headless/app/composables/useProseLinks.ts | 70 +++++++++++++ 7 files changed, 199 insertions(+), 50 deletions(-) create mode 100644 wp-content/themes/headless/acf-json/group_abstract_prose.json create mode 100644 wp-content/themes/headless/app/components/acf/AcfProse.gql create mode 100644 wp-content/themes/headless/app/components/acf/AcfProse.vue create mode 100644 wp-content/themes/headless/app/composables/useProseLinks.ts diff --git a/wp-content/themes/headless/acf-json/group_abstract_builder.json b/wp-content/themes/headless/acf-json/group_abstract_builder.json index 0f369ab..741dd67 100644 --- a/wp-content/themes/headless/acf-json/group_abstract_builder.json +++ b/wp-content/themes/headless/acf-json/group_abstract_builder.json @@ -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 } diff --git a/wp-content/themes/headless/acf-json/group_abstract_prose.json b/wp-content/themes/headless/acf-json/group_abstract_prose.json new file mode 100644 index 0000000..de07aba --- /dev/null +++ b/wp-content/themes/headless/acf-json/group_abstract_prose.json @@ -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 +} diff --git a/wp-content/themes/headless/app/components/acf/AcfProse.gql b/wp-content/themes/headless/app/components/acf/AcfProse.gql new file mode 100644 index 0000000..7134475 --- /dev/null +++ b/wp-content/themes/headless/app/components/acf/AcfProse.gql @@ -0,0 +1,3 @@ +fragment AcfProse on GroupAbstractProse_Fields { + content +} diff --git a/wp-content/themes/headless/app/components/acf/AcfProse.vue b/wp-content/themes/headless/app/components/acf/AcfProse.vue new file mode 100644 index 0000000..6cfbd88 --- /dev/null +++ b/wp-content/themes/headless/app/components/acf/AcfProse.vue @@ -0,0 +1,12 @@ + + + diff --git a/wp-content/themes/headless/app/components/sections/SectionProse.gql b/wp-content/themes/headless/app/components/sections/SectionProse.gql index 6e99684..01bf098 100644 --- a/wp-content/themes/headless/app/components/sections/SectionProse.gql +++ b/wp-content/themes/headless/app/components/sections/SectionProse.gql @@ -1,5 +1,7 @@ fragment SectionProse on GroupAbstractBuilderSectionsProseLayout { - content + prose @nonNull { + ...AcfProse + } layout: layoutSettings @nonNull { ...AcfLayout } diff --git a/wp-content/themes/headless/app/components/sections/SectionProse.vue b/wp-content/themes/headless/app/components/sections/SectionProse.vue index e6971d0..0bc2486 100644 --- a/wp-content/themes/headless/app/components/sections/SectionProse.vue +++ b/wp-content/themes/headless/app/components/sections/SectionProse.vue @@ -6,6 +6,6 @@ defineProps<{ section: SectionProseFragment }>(); diff --git a/wp-content/themes/headless/app/composables/useProseLinks.ts b/wp-content/themes/headless/app/composables/useProseLinks.ts new file mode 100644 index 0000000..5427715 --- /dev/null +++ b/wp-content/themes/headless/app/composables/useProseLinks.ts @@ -0,0 +1,70 @@ +export function useProseLinks(refContent: Ref) { + 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); + } + }); +}