diff --git a/docs/_includes/examples-color-key.html b/_snippets/examples-color-key.md
similarity index 82%
rename from docs/_includes/examples-color-key.html
rename to _snippets/examples-color-key.md
index d7b5553e0..ee7b08712 100644
--- a/docs/_includes/examples-color-key.html
+++ b/_snippets/examples-color-key.md
@@ -1,6 +1,6 @@
To load the template into your n8n instance:
-1. [Download the workflow JSON file](/_workflows/[[ page.meta.workflowFile ]]){:target=_blank .external-link}.
+1. Download the workflow JSON file.
1. Open a new workflow in your n8n instance.
1. Copy in the JSON, or select **Workflow menu** {.off-glb} > **Import from file...**.
diff --git a/docs/advanced-ai/examples/agent-chain-comparison.md b/docs/advanced-ai/examples/agent-chain-comparison.md
index 796a90b77..f6c4e6457 100644
--- a/docs/advanced-ai/examples/agent-chain-comparison.md
+++ b/docs/advanced-ai/examples/agent-chain-comparison.md
@@ -3,18 +3,13 @@
contentType: explanation
title: Agents vs chains
description: A workflow example that demonstrates key differences between agents and chains.
-workflowFile: advanced-ai/examples/agents_vs_chains.json
---
# Demonstration of key differences between agents and chains
In this workflow you can choose whether your chat query goes to an agent or chain. It shows some of the ways that agents are more powerful than chains.
-
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///advanced-ai/examples/agents_vs_chains.json") ]]
## Key features
@@ -28,4 +23,4 @@ This workflow uses:
## Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/advanced-ai/examples/api-workflow-tool.md b/docs/advanced-ai/examples/api-workflow-tool.md
index 064779ca4..595b44249 100644
--- a/docs/advanced-ai/examples/api-workflow-tool.md
+++ b/docs/advanced-ai/examples/api-workflow-tool.md
@@ -3,17 +3,13 @@
contentType: howto
title: Call an API to fetch data
description: Use the n8n workflow tool to load data from an API using the HTTP Request node into your AI workflow.
-workflowFile: advanced-ai/examples/let_your_ai_call_an_api.json
---
# Call an API to fetch data
Use n8n to bring data from any API to your AI. This workflow uses the [Chat Trigger](/integrations/builtin/core-nodes/n8n-nodes-langchain.chattrigger/) to provide the chat interface, and the [Custom n8n Workflow Tool](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/) to call a second workflow that calls the API. The second workflow uses AI functionality to refine the API request based on the user's query.
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///advanced-ai/examples/let_your_ai_call_an_api.json") ]]
## Key features
@@ -26,4 +22,4 @@ This workflow uses:
## Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/advanced-ai/examples/data-google-sheets.md b/docs/advanced-ai/examples/data-google-sheets.md
index bdea11ee7..d298327f1 100644
--- a/docs/advanced-ai/examples/data-google-sheets.md
+++ b/docs/advanced-ai/examples/data-google-sheets.md
@@ -3,17 +3,13 @@
contentType: howto
title: Chat with a Google Sheet using AI
description: Use the n8n workflow tool to load data from Google Sheets into your AI workflow.
-workflowFile: advanced-ai/examples/chat_with_google_sheets_docs_version.json
---
# Chat with a Google Sheet using AI
Use n8n to bring your own data to AI. This workflow uses the [Chat Trigger](/integrations/builtin/core-nodes/n8n-nodes-langchain.chattrigger/) to provide the chat interface, and the [Custom n8n Workflow Tool](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/) to call a second workflow that queries Google Sheets.
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///advanced-ai/examples/chat_with_google_sheets_docs_version.json") ]]
## Key features
@@ -26,4 +22,4 @@ This workflow uses:
## Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/advanced-ai/examples/human-fallback.md b/docs/advanced-ai/examples/human-fallback.md
index 066379b8c..f57c6fa5e 100644
--- a/docs/advanced-ai/examples/human-fallback.md
+++ b/docs/advanced-ai/examples/human-fallback.md
@@ -3,7 +3,6 @@
contentType: howto
title: Set a human fallback for AI workflows
description: Have a workflow that triggers a human answer when the AI can't help.
-workflowFile: advanced-ai/examples/ask_a_human.json
---
# Have a human fallback for AI workflows
@@ -12,10 +11,7 @@ This is a workflow that tries to answer user queries using the standard GPT-4 mo
This workflow uses the [Chat Trigger](/integrations/builtin/core-nodes/n8n-nodes-langchain.chattrigger/) to provide the chat interface, and the [Custom n8n Workflow Tool](/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolworkflow/) to call a second workflow that handles checking for email addresses and sending the Slack message.
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///advanced-ai/examples/ask_a_human.json") ]]
## Key features
@@ -27,4 +23,4 @@ This workflow uses:
## Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/advanced-ai/examples/vector-store-website.md b/docs/advanced-ai/examples/vector-store-website.md
index a7390b68f..f4ef4f948 100644
--- a/docs/advanced-ai/examples/vector-store-website.md
+++ b/docs/advanced-ai/examples/vector-store-website.md
@@ -3,17 +3,13 @@
contentType: howto
title: Populate a Pinecone vector database from a website
description: Scrape a website, load the data into Pinecone, then query it using a chat workflow.
-workflowFile: advanced-ai/examples/populate_a_pinecone_vector_database_from_a_website.json
---
# Populate a Pinecone vector database from a website
Use n8n to scrape a website, load the data into Pinecone, then query it using a chat workflow. This workflow uses the [HTTP node](/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/) to get website data, extracts the relevant content using the [HTML node](/integrations/builtin/core-nodes/n8n-nodes-base.html/), then uses the [Pinecone Vector Store node](/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstorepinecone/) to send it to Pinecone.
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///advanced-ai/examples/populate_a_pinecone_vector_database_from_a_website.json") ]]
## Key features
@@ -27,4 +23,4 @@ This workflow uses:
## Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/credentials/add-edit-credentials.md b/docs/credentials/add-edit-credentials.md
index 4e40a0c57..39273d932 100644
--- a/docs/credentials/add-edit-credentials.md
+++ b/docs/credentials/add-edit-credentials.md
@@ -2,7 +2,6 @@
#https://www.notion.so/n8n/Frontmatter-432c2b8dff1f43d4b1c8d20075510fe4
description: Creating and editing credentials.
contentType: howto
-workflowFile: credentials/dynamic_credentials_using_expressions.json
---
# Create and edit credentials
@@ -31,11 +30,8 @@ You can use expressions to set credentials dynamically as your workflow runs:
### Example workflow
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///credentials/dynamic_credentials_using_expressions.json") ]]
#### Using the example
-[[% include "_includes/examples-color-key.html" %]]
+--8<-- "_snippets/examples-color-key.md"
diff --git a/docs/integrations/builtin/core-nodes/n8n-nodes-base.form.md b/docs/integrations/builtin/core-nodes/n8n-nodes-base.form.md
index 2943d25a4..68a4705d3 100644
--- a/docs/integrations/builtin/core-nodes/n8n-nodes-base.form.md
+++ b/docs/integrations/builtin/core-nodes/n8n-nodes-base.form.md
@@ -3,17 +3,13 @@
title: n8n Form node documentation
description: Documentation for the n8n Form node in n8n, a workflow automation platform. Includes guidance on usage and links to examples.
contentType: integration
-workflowFile: integrations/builtin/core-nodes/n8n-nodes-base.form/mutually-exclusive-branching.json
---
# n8n Form node
Use the n8n Form node to create user-facing forms with multiple steps. You can add other nodes with custom logic between to process user input. You must start the workflow with the [n8n Form Trigger](/integrations/builtin/core-nodes/n8n-nodes-base.formtrigger/).
-
-
-A multi-page form with branching
-
+[[ workflowDemo("file:///integrations/builtin/core-nodes/n8n-nodes-base.form/mutually-exclusive-branching.json") ]]
## Setting up the node
@@ -153,10 +149,7 @@ Form workflows containing mutually exclusive branches work as expected. n8n will
This workflow demonstrates mutually exclusive branching. Each selection can only execute a single branch.
-
-
-[Download the example workflow](/_workflows/[[ page.meta.workflowFile ]])
-
+[[ workflowDemo("file:///integrations/builtin/core-nodes/n8n-nodes-base.form/mutually-exclusive-branching.json") ]]
#### Workflows that may execute multiple branches
@@ -166,14 +159,7 @@ n8n only executes a single **Form Ending** n8n Form node for each execution. Whe
This workflow may execute more than one branch during an execution. Here, n8n executes all valid branches sequentially. This impacts which n8n Form nodes n8n executes (in particular, which **Form Ending** node displays):
-
-
-[Download the example workflow](/_workflows/integrations/builtin/core-nodes/n8n-nodes-base.form/multiple-branch-execution.json)
-
-
-#### Using the examples
-
-[[% include "_includes/examples-color-key.html" %]]
+[[ workflowDemo("file:///integrations/builtin/core-nodes/n8n-nodes-base.form/multiple-branch-execution.json") ]]
### Node options
diff --git a/main.py b/main.py
index def5751a7..a2fee18ae 100644
--- a/main.py
+++ b/main.py
@@ -9,14 +9,14 @@ import os
def define_env(env):
no_template = os.environ.get('NO_TEMPLATE', False)
-
+
# Define the character map and locales as in the original JavaScript version
CHAR_MAP = {"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E\'","Ը":"Y\'","Թ":"T\'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C\'","Կ":"K","Հ":"H","Ձ":"D\'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R\'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P\'","Ք":"Q\'","Օ":"O\'\'","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"\'","’":"\'","“":"\\\"","”":"\\\"","„":"\\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}
-
+
def custom_slugify(string):
if not isinstance(string, str):
raise ValueError("slugify: string argument expected")
-
+
# Process the string
slug = ''.join(
CHAR_MAP.get(ch, ch).replace('-', ' ')
@@ -29,10 +29,10 @@ def define_env(env):
# Replace spaces with hyphen and convert to lowercase
slug = re.sub(r'\s+', '-', slug).lower()
-
+
return slug
- @env.macro
+ @env.macro
def templatesWidget(title: str, slug: str, toLoad: int = 3) -> str:
if no_template:
@@ -84,18 +84,36 @@ def define_env(env):
f''
)
- @env.macro
- def workflowDemo(workflow_endpoint):
+ @env.macro
+ def workflowDemo(workflow_json):
if no_template:
return "
Workflow preview placeholder.
"
- # Original API request logic
- r = requests.get(url = workflow_endpoint)
- wf_data = r.json()
- template_url = f'https://n8n.io/workflows/{wf_data["id"]}-{wf_data["name"]}/'
- workflow_json = {
- "nodes": wf_data['workflow']['nodes'],
- "connections": wf_data['workflow']['connections']
- }
+ parsed_workflow_url = urllib.parse.urlparse(workflow_json)
+
+ if parsed_workflow_url.scheme in ["https", "http"]:
+ r = requests.get(url = workflow_json)
+ wf_data = r.json()
+ template_url = f'https://n8n.io/workflows/{wf_data["id"]}-{custom_slugify(wf_data["name"])}/'
+ workflow_json = {
+ "nodes": wf_data['workflow']['nodes'],
+ "connections": wf_data['workflow']['connections']
+ }
+ workflow_message = "View template details"
+ elif parsed_workflow_url.scheme == "file":
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+ request_path = parsed_workflow_url.path
+ file_path = f'{BASE_DIR}/docs/_workflows{request_path}'
+ with open(file_path, 'r') as file:
+ wf_data = json.load(file)
+ template_url = f'/_workflows{request_path}'
+ workflow_json = {
+ "nodes": wf_data['nodes'],
+ "connections": wf_data['connections']
+ }
+ workflow_message = "View workflow file"
+ else:
+ raise ValueError("Workflow JSON must include a URL scheme")
+
encoded_workflow_json = urllib.parse.quote(json.dumps(workflow_json))
- return f""
+ return f""