diff --git a/.eleventy.js b/.eleventy.js index f9b28d6f71..ac251b91fb 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -221,6 +221,7 @@ module.exports = function(eleventyConfig) { eleventyConfig.addLayoutAlias('page', 'layouts/page.njk'); eleventyConfig.addLayoutAlias('nohero', 'layouts/nohero.njk'); eleventyConfig.addLayoutAlias('solution', 'layouts/solution.njk'); + eleventyConfig.addLayoutAlias('use-case', 'layouts/use-case.njk'); eleventyConfig.addLayoutAlias('catalog', 'layouts/catalog.njk'); eleventyConfig.addLayoutAlias('redirect', 'layouts/redirect.njk'); diff --git a/src/_includes/components/related-resources.njk b/src/_includes/components/related-resources.njk new file mode 100644 index 0000000000..33984b912d --- /dev/null +++ b/src/_includes/components/related-resources.njk @@ -0,0 +1,56 @@ +{# ============================================================ + RELATED RESOURCES (skeleton) + Three columns: Case studies / White papers / Blog. + Driven by a tag passed in as `relatedTag` (e.g. "industry:food-beverage" + or "usecase:track-and-trace"). Resources opt in later by adding that tag; + the matching tag collection is then split by section. + No existing customer stories are tagged, so every column renders the + empty "More coming soon" state. + ============================================================ #} +{% set relatedTag = relatedTag or "" %} +{% set tagged = collections[relatedTag] or [] %} + +{% set caseStudies = [] %} +{% set whitepapers = [] %} +{% set blogPosts = [] %} +{% for item in tagged %} + {% if "/customer-stories/" in item.url %} + {% set caseStudies = (caseStudies.push(item), caseStudies) %} + {% elif "/whitepaper/" in item.url %} + {% set whitepapers = (whitepapers.push(item), whitepapers) %} + {% elif "/blog/" in item.url %} + {% set blogPosts = (blogPosts.push(item), blogPosts) %} + {% endif %} +{% endfor %} + +{% set columns = [ + {heading: "Case studies", items: caseStudies}, + {heading: "White papers", items: whitepapers}, + {heading: "Blog", items: blogPosts} +] %} + +
+
+

Related resources

+
+ {% for column in columns %} +
+

{{ column.heading }}

+ {% if column.items.length %} + + {% else %} +
+

More coming soon

+
+ {% endif %} +
+ {% endfor %} +
+
+
diff --git a/src/_includes/layouts/use-case.njk b/src/_includes/layouts/use-case.njk new file mode 100644 index 0000000000..0996911bc4 --- /dev/null +++ b/src/_includes/layouts/use-case.njk @@ -0,0 +1,276 @@ +--- +layout: layouts/base.njk +sitemapPriority: 0.7 +--- +{# ============================================================ + USE CASE LAYOUT (content-driven, pain-led narrative) + + Per-page front-matter (rich, preferred): + problem hero sub-headline (the pain in one line) + customerPain { heading, intro[], cards[ {icon,title,detail} ] } + outcomeFirst { heading, intro, dimensions[ {label,title,detail} ] } + whyItMatters { heading, intro, points[ {title,detail} ] } + competition { heading, intro, traps[ {label,title,detail} ] } + comparison { without[ {title,detail} ], with[ {title,detail} ] } + + Legacy fall-back front-matter (simple skeleton, still supported): + gap[], workflow[], outcomes[] + + No customer names and no attributed quotes on the public page. + ============================================================ #} + +{# --- build the sticky section nav from the blocks that exist --- #} +{% set nav = [] %} +{% if customerPain %}{% set nav = nav.concat([{ id: "customer-pain", label: "Customer Pain" }]) %}{% endif %} +{% if outcomeFirst %}{% set nav = nav.concat([{ id: "outcome-first", label: "Outcome First" }]) %}{% endif %} +{% if whyItMatters %}{% set nav = nav.concat([{ id: "why-it-matters", label: "Why It Matters" }]) %}{% endif %} +{% if competition %}{% set nav = nav.concat([{ id: "competition", label: "Why Off-the-Shelf Fails" }]) %}{% endif %} +{% if comparison %}{% set nav = nav.concat([{ id: "with-without", label: "With / Without FlowFuse" }]) %}{% endif %} + +
+ + +
+
+

Use case

+

{{ title }}

+

{{ problem }}

+ +
+
+ + {% if nav.length %} + + + {% endif %} + + {% if customerPain %} + +
+
+

01 · Customer pain

+

{{ customerPain.heading }}

+
+ {% for paragraph in customerPain.intro %} +

{{ paragraph }}

+ {% endfor %} +
+
+ {% for card in customerPain.cards %} +
+
+ {% include "components/icons/" + card.icon + ".svg" %} +
+

{{ card.title }}

+

{{ card.detail }}

+
+ {% endfor %} +
+
+
+ {% endif %} + + {% if outcomeFirst %} + +
+
+

02 · Outcome first

+

{{ outcomeFirst.heading }}

+

{{ outcomeFirst.intro }}

+
+ {% for dim in outcomeFirst.dimensions %} +
+ {{ dim.label }} +

{{ dim.title }}

+

{{ dim.detail }}

+
+ {% endfor %} +
+
+
+ {% endif %} + + {% if whyItMatters %} + +
+
+

03 · Why this is important

+

{{ whyItMatters.heading }}

+

{{ whyItMatters.intro }}

+
+ {% for point in whyItMatters.points %} +
+ {% if loop.index < 10 %}0{% endif %}{{ loop.index }} +
+

{{ point.title }}

+

{{ point.detail }}

+
+
+ {% endfor %} +
+
+
+ {% endif %} + + {% if competition %} + +
+
+

04 · Why off-the-shelf doesn't work

+

{{ competition.heading }}

+

{{ competition.intro }}

+
+ {% for trap in competition.traps %} +
+
+ {% include "components/icons/x-circle.svg" %} + {{ trap.label }} +
+

{{ trap.title }}

+

{{ trap.detail }}

+
+ {% endfor %} +
+
+
+ {% endif %} + + {% if comparison %} + +
+
+

05 · With / without FlowFuse

+
+
+

Without FlowFuse

+
+ {% for row in comparison.without %} +
+ {% include "components/icons/x-mark.svg" %} +
+
{{ row.title }}
+

{{ row.detail }}

+
+
+ {% endfor %} +
+
+
+

With FlowFuse

+
+ {% for row in comparison.with %} +
+ {% include "components/icons/check-circle.svg" %} +
+
{{ row.title }}
+

{{ row.detail }}

+
+
+ {% endfor %} +
+
+
+
+
+ {% endif %} + + {# ============================================================ + LEGACY SKELETON FALL-BACK (only when no rich blocks defined) + ============================================================ #} + {% if not nav.length %} + {% if gap %} +
+
+

The operational gap

+
+ {% for paragraph in gap %} +

{{ paragraph }}

+ {% endfor %} +
+

Placeholder copy. Generic operational framing for this workflow pattern.

+
+
+ {% endif %} + {% if workflow %} +
+
+

The operational workflow

+
    + {% for item in workflow %} +
  • + {% include "components/icons/check.svg" %} + {{ item }} +
  • + {% endfor %} +
+
+
+ {% endif %} + {% if outcomes %} +
+
+

Outcomes

+
+ {% for outcome in outcomes %} +
+ {% include "components/icons/arrow-trending-up.svg" %} +

{{ outcome }}

+
+ {% endfor %} +
+

Placeholder outcomes. No customer names or real figures.

+
+
+ {% endif %} + {% endif %} + + + {% set relatedTag = "usecase:" + page.fileSlug %} + {% include "components/related-resources.njk" %} + + +
+
+

See it on your operation

+

Talk to an expert, or get started with FlowFuse today.

+ +
+
+ +
diff --git a/src/use-cases/_template.njk b/src/use-cases/_template.njk new file mode 100644 index 0000000000..a4240e01d7 --- /dev/null +++ b/src/use-cases/_template.njk @@ -0,0 +1,102 @@ +--- +# =================================================================== +# Use-case page TEMPLATE. +# +# This file is intentionally NOT rendered (permalink: false) and is +# NOT included in the `use-case` collection. It exists as a copy-and- +# rename starting point for new use-case pages. +# +# To create a new use-case page: +# 1. Copy this file to `src/use-cases/.njk` +# 2. Replace the placeholder values below +# 3. Make sure `tags` keeps `use-case` so the page appears in the +# `/use-cases/` hub grid +# +# The layout renders a pain-led narrative from the rich blocks below +# (customerPain, outcomeFirst, whyItMatters, competition, comparison) +# plus a sticky section nav. Every block is optional: a section only +# renders when its block is present. Keep copy generic, with no +# customer names and no attributed quotes. +# +# Icon names refer to files in src/_includes/components/icons/. +# =================================================================== +permalink: false +eleventyExcludeFromCollections: true +layout: use-case +tags: + - use-case +title: "[Use case title]" +meta: + title: "[Use case title] | Use Cases | FlowFuse" + description: "[One-sentence summary of the use case. Placeholder.]" +problem: "[The pain in one line. This is the hero sub-headline. Placeholder.]" + +# 01 -- Customer pain +customerPain: + heading: "[One-line statement of the core pain.]" + intro: + - "[First framing paragraph.]" + - "[Second framing paragraph.]" + cards: + - icon: "clock" + title: "[Pain symptom.]" + detail: "[One or two sentences.]" + - icon: "clip-list" + title: "[Pain symptom.]" + detail: "[One or two sentences.]" + +# 02 -- Outcome first +outcomeFirst: + heading: "[Reframe around the outcome the buyer defines.]" + intro: "[Why there is no one-size-fits-all answer.]" + dimensions: + - label: "Operational" + title: "[Outcome.]" + detail: "[One or two sentences.]" + - label: "Financial" + title: "[Outcome.]" + detail: "[One or two sentences.]" + +# 03 -- Why this is important +whyItMatters: + heading: "[Why the gap compounds if left unaddressed.]" + intro: "[One framing sentence.]" + points: + - title: "[Reason.]" + detail: "[One or two sentences.]" + - title: "[Reason.]" + detail: "[One or two sentences.]" + +# 04 -- Why off-the-shelf / competition does not work +competition: + heading: "[Why generic tools fit this operation poorly.]" + intro: "[One framing sentence.]" + traps: + - label: "Trap 01" + title: "[Trap.]" + detail: "[One or two sentences.]" + - label: "Trap 02" + title: "[Trap.]" + detail: "[One or two sentences.]" + +# 05 -- With / without FlowFuse +comparison: + without: + - title: "[Status quo pain.]" + detail: "[One or two sentences.]" + with: + - title: "[FlowFuse capability.]" + detail: "[One or two sentences.]" + +# --------------------------------------------------------------- +# Legacy minimal fall-back (still supported). If you only set these +# and omit the rich blocks above, the layout renders a simple +# gap / workflow / outcomes skeleton instead. +# --------------------------------------------------------------- +# gap: +# - "[Paragraph.]" +# workflow: +# - "[Step.]" +# outcomes: +# - "[Outcome.]" +--- diff --git a/src/use-cases/index.njk b/src/use-cases/index.njk new file mode 100644 index 0000000000..c7dfb199ec --- /dev/null +++ b/src/use-cases/index.njk @@ -0,0 +1,57 @@ +--- +layout: layouts/base.njk +sitemapPriority: 0.8 +title: "Use Cases" +meta: + title: "Use Cases | FlowFuse" + description: "Generic operational workflow patterns for industrial teams. Turn events into action with FlowFuse. Placeholder skeleton hub." +--- +
+ + +
+
+

Use cases

+

Turn industrial events into action

+

Operational workflow patterns that follow Event, Decision, Action. Explore how each one is operationalized with FlowFuse.

+ +
+
+ + +
+
+
+ {% for uc in collections["use-case"] | sort(false, true, "data.title") %} + +

{{ uc.data.title }}

+

{{ uc.data.problem }}

+ + View use case + {% include "components/icons/arrow-right.svg" %} + +
+ {% endfor %} +
+
+
+ + + {% set relatedTag = "" %} + {% include "components/related-resources.njk" %} + + +
+
+

See it on your workflow

+

Talk to an expert, or get started with FlowFuse today.

+ +
+
+ +