### Install edge-markdown Plugin
Source: https://edgejs.dev/docs/edge-markdown
Install the edge-markdown plugin using npm.
```bash
npm i edge-markdown
```
--------------------------------
### Install Iconify JSON Bundle
Source: https://edgejs.dev/docs/edge-iconify
Install a specific Iconify icon bundle, such as heroicons, using npm.
```bash
npm i @iconify-json/heroicons
```
--------------------------------
### Basic Hello World in Edge
Source: https://edgejs.dev/
A simple "Hello World" example demonstrating basic variable interpolation in Edge templates.
```edge
Hello {{ user.username }}!
```
--------------------------------
### Install Edge.js v6
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
Install the latest version of Edge.js, which is tagged with `@next`.
```bash
npm i edge.js@next
```
--------------------------------
### Install Edge.js
Source: https://edgejs.dev/docs/getting_started
Install the Edge.js package using npm. This is the first step to using Edge in your Node.js project.
```bash
npm i edge.js
```
--------------------------------
### Install edge-iconify Package
Source: https://edgejs.dev/docs/edge-iconify
Install the edge-iconify npm package to enable Iconify integration.
```bash
npm i edge-iconify
```
--------------------------------
### Project Structure Example
Source: https://edgejs.dev/docs/getting_started
A typical project structure for an Edge.js application, showing the placement of views and the main application file.
```treeview
.\n\n├── views\n│ └── home.edge\n├── index.js\n└── package.json
```
--------------------------------
### Using Edge Components
Source: https://edgejs.dev/
An example showcasing Edge's component system, which allows for reusable markup with isolated state, using accordions as a demonstration.
```edge
@accordion()
@accordion.item({ title: 'What is Edge?' })
Edge is a template engine for Node.js
@end
@accordion.item({ title: 'Why should I use Edge?' })
Because you need a template engine 🤷🏻♂️
@end
@accordion.item({ title: 'How can I support Edge?' })
By becoming a sponsor on Github
@end
@end
```
--------------------------------
### Rendering a Map with Markers using Provide/Inject
Source: https://edgejs.dev/docs/components/provide_inject
This example demonstrates how to use the Provide/Inject API to render a map with multiple markers. The parent `map` component injects map data, and child `map.marker` components push marker information to the injected array.
```edge
@map({ center: [-84, 35], zoom: 3 })
@!map.marker({ lat: 37.8225, lon: -122.0024, label: 'Edge Body Shaping' })
@!map.marker({ lat: 33.8981, lon: -118.4169, label: 'Edge Barbershop & Essentials' })
@!map.marker({ lat: 29.723, lon: -95.4189, label: 'Edge Waxing Studio' })
@!map.marker({ lat: 28.3378, lon: -81.3966, label: 'Edge 30 Nutritional Consultants' })
@!map.marker({ lat: 40.6483, lon: -74.0237, label: 'Edge Brands LLC' })
@end
```
--------------------------------
### Configure Shiki Syntax Highlighting
Source: https://edgejs.dev/docs/edge-markdown
Customize Shiki syntax highlighting by providing a theme and specifying supported languages. Ensure Shiki is installed and configured in your project.
```javascript
import { edgeMarkdown } from 'edge-markdown'
edge.use(edgeMarkdown({
shiki: {
theme: 'github-dark',
langs: ['javascript', 'typescript', 'json']
}
}))
```
--------------------------------
### Access Global Configuration in HTML
Source: https://edgejs.dev/docs/templates_state
Access global properties directly within your HTML templates using dot notation. This example shows how to apply a global color scheme and iterate over menu items.
```html
@each(item in config.menu)
@end
```
--------------------------------
### Mount Default Disk for Templates
Source: https://edgejs.dev/docs/getting_started
Register the 'views' directory as the default disk for Edge.js to locate templates. This example shows how to mount a directory and then render templates from it.
```javascript
const BASE_URL = new URL('./', import.meta.url)\n\n\n\nedge.mount(new URL('views', BASE_URL))\n\n\n\n/**\n * Render home.edge file from\n * {BASE_URL/views} directory\n */\nawait edge.render('home')\n\n\n\n/**\n * Render pages/posts/index.edge file from\n * {BASE_URL/views} directory\n */\nawait edge.render('pages/posts/index')
```
--------------------------------
### Extend Layout and Render Slots
Source: https://edgejs.dev/docs/components/layouts
Extend a defined layout in a specific view file. This example shows how to pass a title, define content for the 'meta' slot, and provide content for the 'main' slot.
```edge
@layout.app({ title: "Welcome page title" })
@slot('meta')
@endslot
@slot('main')
Hello world
@endslot
@end
```
--------------------------------
### Run Node.js server with inspect flag
Source: https://edgejs.dev/docs/debugging
To enable debugging with the `debugger` tag, run your Node.js server using the `--inspect` flag. This command starts the server and makes it available for debugging connections.
```bash
node --inspect index.js
```
--------------------------------
### Register edge-iconify Plugin
Source: https://edgejs.dev/docs/edge-iconify
Register the edge-iconify plugin with Edge.js after installation.
```javascript
import edge from 'edge.js'
import { edgeIconify } from 'edge-iconify'
edge.use(edgeIconify)
```
--------------------------------
### Call Global Async Function in Template
Source: https://edgejs.dev/docs/templates_state
Call globally defined asynchronous functions within your templates using the `@let` tag to assign the result to a variable. The example fetches a user and displays their username.
```edge
@let(user = await findUser(1))
{{ user.username }}
```
--------------------------------
### Define and Render Markdown Slots in Hero Component
Source: https://edgejs.dev/docs/edge-markdown
Use the `#` tag to define slots and `@markdownSlot` to render their content within an Edge component. This example shows a 'hero' component with a default slot and a named 'description' slot.
```edge
::hero
Default slot text
#description
This will be rendered inside the `description` slot.
::
```
```edge
@markdownSlot()
@markdownSlot('description')
```
--------------------------------
### Register a Simple Custom Edge Tag
Source: https://edgejs.dev/docs/creating-custom-tags
Implement the TagContract interface to define a custom tag and register it using edge.registerTag. This example creates a 'reverse' tag that outputs static text.
```javascript
import edge from 'edge.js'
import { TagContract } from 'edge.js/types'
/**
* Defining a tag
*/
const reverse: TagContract = {
block: false,
seekable: true,
tagName: 'reverse',
compile(parser, buffer, token) {
buffer.outputRaw('Hello from reverse tag')
}
}
/**
* Registering it with Edge
*/
edge.registerTag(reverse)
/**
* Using the tag
*/
const output = await edge.renderRaw('@reverse()')
console.log(output) // I am the reverse tag
```
--------------------------------
### Get Specific Props
Source: https://edgejs.dev/docs/components/props
Extract a subset of props based on a list of keys using `$props.only()` and then access a specific prop's value.
```edge
{{ $props.only(['text', 'class']).get('text') }}
```
--------------------------------
### Global Helper Changes
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
Replaced global helpers with their respective module-specific functions. For example, `e` is replaced by `html.escape`, `stringify` by `js.stringify`, and `safe` by `html.safe`.
```edge
{{ e(post.content) }}
{{ html.escape(post.content) }}
{{ stringify(someJSONObject) }}
{{ js.stringify(someJSONObject) }}
{{ safe(post.content) }}
{{ html.safe(post.content) }}
```
--------------------------------
### Accessing Shared State with $context
Source: https://edgejs.dev/docs/components/provide_inject
Child components can access state injected by their parent using the `$context` variable. This example shows how to inspect the entire context object.
```edge
@map()
{{ inspect($context) }}
@end
```
--------------------------------
### Render Components with @component Tag
Source: https://edgejs.dev/docs/components/introduction
Use the `@component` tag to render components, passing the template path and props. This example shows rendering a button component twice with different text and types.
```edge
```
--------------------------------
### Basic Hello World in Edge
Source: https://edgejs.dev/docs/introduction
A simple greeting template demonstrating basic Edge syntax.
```edge
Hello {{ user.username }}!
```
--------------------------------
### Initialize Edge with Iconify and Add Collection
Source: https://edgejs.dev/docs/edge-iconify
Initialize Edge.js, import necessary functions from edge-iconify, add an icon collection, and register the plugin.
```javascript
import { Edge } from 'edge.js'
import { edgeIconify, addCollection } from 'edge-iconify'
import { icons as heroIcons } from '@iconify-json/heroicons'
/**
* Add heroIcons collection
*/
addCollection(heroIcons)
const edge = Edge.create()
/**
* Register the plugin
*/
edge.use(edgeIconify)
```
--------------------------------
### Get Prop Value
Source: https://edgejs.dev/docs/components/props
Retrieve the value of a specific prop using the `$props.get()` method.
```edge
{{ $props.get('text') }}
```
--------------------------------
### Render Input Component with Props
Source: https://edgejs.dev/docs/components/props
Demonstrates how to render the input component and pass specific props such as name and placeholder.
```edge
@!input({
name: 'title',
placeholder: 'Enter post title'
})
@!input({
name: 'slug',
placeholder: 'Enter post post slug'
})
```
--------------------------------
### Configure Compatibility Plugin
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
Use the `migrate` plugin to maintain compatibility with version 5 if your project is not yet ready for all breaking changes.
```javascript
import edge from 'edge.js'
import { migrate } from 'edge.js/plugins/migrate'
edge.use(migrate)
```
--------------------------------
### Pass Content to Component Slot
Source: https://edgejs.dev/docs/components/introduction
Content placed between the opening and closing `@component` tags is passed to the default slot. This example passes an icon and text to the button component.
```edge
@component('components/button', {
class: ['flex', 'align-center', 'space-x-4']
})
Login
@end
```
--------------------------------
### Basic Node.js HTTP Server with Edge.js
Source: https://edgejs.dev/docs/getting_started
Set up a basic Node.js HTTP server that renders an Edge.js template. Ensure your application uses ES modules.
```javascript
import { Edge } from 'edge.js'\n\nimport { createServer } from 'node:http'\n\n\n\nconst edge = Edge.create()\nedge.mount(new URL('./views', import.meta.url))\n\n\n\nconst server = createServer(async (req, res) => {\n const data = { username: 'virk' }\n const html = await edge.render('home', data)\n\n res.setHeader('content-type', 'text/html')\n res.end(html)\n})\n\n\n\nserver.listen(3000)
```
--------------------------------
### Merge Additional Classes to Input
Source: https://edgejs.dev/docs/components/props
Illustrates how to merge additional specific classes with the default 'input' class for more granular styling.
```edge
@input({
type: 'text',
name: 'title',
id: 'title',
class: [
'input-medium',
'input-rounded'
]
})
```
--------------------------------
### Looping Over Collections in Edge
Source: https://edgejs.dev/
Demonstrates how to loop over arrays or objects using Edge's unified loop syntax, including rendering partials for each item.
```edge
@each(comment in post.comments)
@include('partials/comment')
@end
```
--------------------------------
### Example Usage of @notification Tag
Source: https://edgejs.dev/docs/creating-custom-tags
Demonstrates how to use the custom '@notification' tag in an Edge.js template. The tag conditionally renders its content based on the presence of a notification for a given type.
```edge
@notification('success')
{{ notification.message }}
@end
```
--------------------------------
### Merge Props with Default Values
Source: https://edgejs.dev/docs/components/props
Use `$props.merge()` to combine custom properties with existing props. Existing props take precedence. This example sets a default 'type' attribute.
```edge
```
--------------------------------
### Mutate Inline Variable with `@assign`
Source: https://edgejs.dev/docs/templates_state
Re-assign new values to inline variables within a template using the `@assign` tag. This example demonstrates mutating a `total` variable inside an `each` loop.
```edge
{{-- Define variable --}}
@let(total = 0)
@each(item in items)
{{-- Re-assign it a new value --}}
@assign(total = total + item.price)
{{ item.name }} = {{ item.price }}
@end
Gross total = {{ total }}
```
--------------------------------
### Mount Multiple Named Disks for Theming
Source: https://edgejs.dev/docs/getting_started
Register multiple named disks to manage different template sets, such as themes. This allows switching between template directories easily.
```javascript
const BASE_URL = new URL('./', import.meta.url)\n\n\n\nedge.mount(\n 'elegant',\n new URL('themes/elegant', BASE_URL)\n)\n\n\n\nedge.mount(\n 'classic',\n new URL('themes/classic', BASE_URL)\n)\n\n\n\nedge.mount(\n 'mono',\n new URL('themes/mono', BASE_URL)\n)
```
--------------------------------
### Using Async/Await in Edge Templates
Source: https://edgejs.dev/
Illustrates the use of async/await keywords directly within Edge templates for handling asynchronous operations.
```edge
@if(user.hasSubscription)
Hurray! You have access to over 280 videos.
@else
Videos are available only to subscribers.
@end
```
--------------------------------
### Define a Base Layout with Slots
Source: https://edgejs.dev/docs/components/layouts
Create a reusable layout file that defines placeholders for dynamic content using slots. This layout includes a default title and allows overriding meta and main content sections.
```edge
{{ title || "Your default title" }}
@if ($slots.meta)
{{{ await $slots.meta() }}}
@endif
{{{ await $slots.main() }}}
```
--------------------------------
### Update edge-stacks and edge-iconify
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
Ensure `edge-stacks` and `edge-iconify` are updated to their latest `@next` versions if you are using them.
```bash
npm i edge-stacks@next
npm i edge-iconify@next
```
--------------------------------
### Push Content to the Top of a Stack
Source: https://edgejs.dev/docs/stacks
Use `@pushToTop` to prepend content to a specified stack. This is useful for ensuring certain content appears before other content that is pushed to the same stack.
```edge
@pushTo('world')
hello!
@end
@pushToTop('world')
hey!
@end
```
--------------------------------
### renderSync
Source: https://edgejs.dev/docs/getting_started
The `renderSync` method renders template files using synchronous APIs. It is recommended to use the `render` method instead.
```APIDOC
## renderSync
### Description
The `renderSync` method is similar to the `render`. However, it uses synchronous APIs under the hood to read and render the template files. We recommend using the `render` method over the `renderSync` method.
### Method
```javascript
edge.renderSync(templateName: string)
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```javascript
const html = edge.renderSync('home')
console.log(html)
```
### Response
#### Success Response (200)
- **html** (string) - The rendered HTML content.
#### Response Example
```json
{
"html": "
Example HTML
"
}
```
```
--------------------------------
### Render Templates from Named Disks
Source: https://edgejs.dev/docs/getting_started
Render templates by specifying the disk name as a prefix to the template path. This is useful when using multiple named disks.
```javascript
await edge.render('classic::home')\nawait edge.render('mono::pages/posts/index')
```
--------------------------------
### Configure edge-markdown Plugin Options
Source: https://edgejs.dev/docs/edge-markdown
Customize Markdown processing behavior by passing configuration options to the edgeMarkdown function. Options include prefix, highlighting, HTML allowance, TOC generation, and plugin registration.
```javascript
edge.use(edgeMarkdown({
prefix: 'markdown',
highlight: true,
allowHTML: true,
toc: {
enabled: true,
maxDepth: 2,
},
remarkPlugins: [],
rehypePlugins: [],
components: {},
allowedTags: [],
hooks: [
(node) => {},
]
}))
```
--------------------------------
### Creating Accordion Components
Source: https://edgejs.dev/docs/introduction
Demonstrates the usage of Edge components, specifically an accordion, to create reusable UI elements with collapsible content.
```edge
@accordion()
@accordion.item({ title: 'What is Edge?' })
Edge is a template engine for Node.js
@end
@accordion.item({ title: 'Why should I use Edge?' })
Because you need a template engine 🤷🏻♂️
@end
@accordion.item({ title: 'How can I support Edge?' })
By becoming a sponsor on Github
@end
@end
```
--------------------------------
### Define an Input Component with Props
Source: https://edgejs.dev/docs/components/props
This snippet shows how to define an input component that accepts various props like type, placeholder, name, and value, providing default values where applicable.
```edge
```
--------------------------------
### Use a Card Component with Named Slots
Source: https://edgejs.dev/docs/components/slots
This snippet demonstrates how to use the card component defined with named slots. Provide content for each slot using the @slot('slotName') ... @end syntax.
```edge
@card({ class: ['card-lg', 'card-shadow'] })
@slot('header')
Quick start
@end
@slot('content')
Start building your next project in minutes
@end
@end
```
--------------------------------
### renderRawSync
Source: https://edgejs.dev/docs/getting_started
The `renderRawSync` method is similar to `renderRaw` but uses synchronous APIs for rendering raw text templates.
```APIDOC
## renderRawSync
### Description
The `renderRawSync` method is the same as `renderRaw` but uses synchronous APIs under the hood. It renders raw text as a template synchronously.
### Method
```javascript
edge.renderRawSync(template: string, data?: object)
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **template** (string) - The raw template string to render.
- **data** (object) - Optional. An object containing data to be used within the template.
### Request Example
```javascript
const template = `
Hello {{ username || 'Guest' }}!
`
edge.renderRawSync(template, { username: 'virk' })
```
### Response
#### Success Response (200)
- **html** (string) - The rendered HTML content.
#### Response Example
```json
{
"html": "
Hello virk!
"
}
```
```
--------------------------------
### Rendering Markdown Preview
Source: https://edgejs.dev/docs/edge-markdown
Generate a preview of Markdown content, rendering only the text before the first `h2` heading, using the `$markdown.preview` method. This is useful for summaries.
```edge
@let(doc = await $markdown.preview({
file: absolutePathToMdFile
}))
{{{ doc.content }}}
```
--------------------------------
### Render Template Using render Method
Source: https://edgejs.dev/docs/getting_started
Use the `edge.render` method to render a template file. It takes the template path and an optional data object. The method returns the rendered HTML as a string.
```javascript
const html = await edge.render('home')\nconsole.log(html)
```
--------------------------------
### Define Reusable Markdown Components
Source: https://edgejs.dev/docs/edge-markdown
Create reusable Edge components for Markdown content using MDC syntax. Components are automatically loaded from the `components/[prefix]` directory.
```edge
{{ title }}
@markdownSlot()
```
```edge
::alert{title="Important" type="warning"}
This is a warning alert with **markdown content** inside.
::
::alert{title="Tip"}
You can also use components with slots.
::
```
--------------------------------
### Render Component with Overridden Prop
Source: https://edgejs.dev/docs/components/props
Shows how to render a component and override a prop that might have a default value set using `$props.merge()`.
```edge
@!component('components/button', { type: 'reset' })
```
--------------------------------
### AST for Raw String Argument
Source: https://edgejs.dev/docs/creating-custom-tags
Demonstrates the AST generated when a custom tag receives a raw string literal as an argument.
```edge
@reverse('hello world')
```
```json
{
"type": "Literal",
"start": 0,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 13
}
},
"value": "hello world",
"raw": "'hello world'"
}
```
--------------------------------
### Define Global Configuration
Source: https://edgejs.dev/docs/templates_state
Use `edge.global` to define global properties accessible by all templates. This is useful for sharing configuration like website settings.
```javascript
edge.global('config', {
colorScheme: 'dark',
menu: [],
socialLinks: [],
})
```
--------------------------------
### Looping Over Collections
Source: https://edgejs.dev/docs/introduction
Illustrates how to iterate over arrays or objects using the @each directive for displaying collections of data.
```edge
@each(comment in post.comments)
@include('partials/comment')
@end
```
--------------------------------
### Using Conditionals with Async/Await
Source: https://edgejs.dev/docs/introduction
Shows how to use conditional logic (@if/@else/@end) in Edge templates, including scenarios involving async operations.
```edge
@if(user.hasSubscription)
Hurray! You have access to over 280 videos.
@else
Videos are available only to subscribers.
@end
```
--------------------------------
### Define a Stack in Main Layout
Source: https://edgejs.dev/docs/stacks
Use the `@stack` tag to create a named placeholder in your main layout. This stack can then be populated by other templates using push tags.
```edge
@stack('js')
@stack('world')
@!dialog()
```
--------------------------------
### Basic Edge.js Template
Source: https://edgejs.dev/docs/getting_started
A simple Edge.js template file that displays a dynamic greeting using a variable.
```edge
\n\n\n\n\t\n\n\n\n
\n Hello {{ username }}\n
\n\n\n
```
--------------------------------
### Input Component with Default Classes
Source: https://edgejs.dev/docs/components/props
Shows the output HTML when a component is rendered with default classes applied via `$props.merge()`.
```html
```
--------------------------------
### Reference Component from Named Disk as Tag
Source: https://edgejs.dev/docs/components/introduction
Components from named disks can be referenced as tags by prefixing the disk name, followed by a dot.
```edge
{{-- Component as a tag from the uikit disk --}}
@!uikit.input()
{{-- Via component tag --}}
@!component('uikit::input')
```
--------------------------------
### Use a Card Component with a Main Slot
Source: https://edgejs.dev/docs/components/slots
This snippet demonstrates using the card component with a main slot. The content provided directly within the component tag will be rendered in the main slot.
```edge
@card({ title: 'Quick start' })
Start building your next project in minutes
@end
```
--------------------------------
### renderRaw
Source: https://edgejs.dev/docs/getting_started
The `renderRaw` method allows rendering raw text as a template, supporting asynchronous operations.
```APIDOC
## renderRaw
### Description
The `renderRaw` method allows you to render raw text as a template. It supports asynchronous operations for rendering.
### Method
```javascript
await edge.renderRaw(template: string, data?: object)
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **template** (string) - The raw template string to render.
- **data** (object) - Optional. An object containing data to be used within the template.
### Request Example
```javascript
const template = `
Hello {{ username || 'Guest' }}!
`
await edge.renderRaw(template, { username: 'virk' })
```
### Response
#### Success Response (200)
- **html** (string) - The rendered HTML content.
#### Response Example
```json
{
"html": "
Hello virk!
"
}
```
```
--------------------------------
### Uninstall edge-supercharged
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
The functionality of the `edge-supercharged` plugin is now integrated into Edge directly, so this package can be uninstalled.
```bash
npm uninstall edge-supercharged
```
--------------------------------
### Push Content to a Stack
Source: https://edgejs.dev/docs/stacks
Use the `@pushTo` tag to append content to a specified stack. This tag can be used multiple times, and each invocation will add its content to the stack.
```edge
@pushTo('world')
hello!
@end
```
--------------------------------
### Render Slot Content in Component
Source: https://edgejs.dev/docs/components/introduction
Use `$slots.main()` to render the default slot content within a component. The `$props.toAttrs()` method is used to apply props as HTML attributes.
```edge
```
--------------------------------
### Include Partial from Another Disk - EdgeJS
Source: https://edgejs.dev/docs/partials
Include partials from different disks by prefixing the disk name to the template path within the `@include` tag.
```html
@include('shared::partials/header')
@include('shared::partials/footer')
```
--------------------------------
### Evaluating JavaScript Expressions
Source: https://edgejs.dev/docs/introduction
Demonstrates evaluating JavaScript expressions, including asynchronous operations like fetching data, within Edge templates.
```edge
@let(payments = await user.getPayments())
You have made {{ payments.length }} payments so far.
```
--------------------------------
### Output HTML with Merged Classes
Source: https://edgejs.dev/docs/components/props
The resulting HTML when multiple specific classes are merged with the base 'input' class.
```html
```
--------------------------------
### Create a Button Component
Source: https://edgejs.dev/docs/components/introduction
Define a reusable button component in `components/button.edge`. It accepts `type` and `text` as props.
```edge
```
--------------------------------
### Reference Component from Named Disk
Source: https://edgejs.dev/docs/components/introduction
Components stored on named disks can be referenced by prefixing the disk name, followed by `::`.
```edge
@!component('uikit::components/button', { text: 'Login' })
```
--------------------------------
### AST for Variable Reference Argument
Source: https://edgejs.dev/docs/creating-custom-tags
Illustrates the AST structure when a custom tag argument is a reference to a variable.
```edge
@reverse(username)
```
```json
{
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "state"
},
"computed": false,
"property": {
"type": "Identifier",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 8
}
},
"name": "username"
}
}
```
--------------------------------
### Push Content Once to a Stack
Source: https://edgejs.dev/docs/stacks
Use `@pushOnceTo` to add content to a stack only the first time the tag is encountered. This prevents duplicate content, such as script tags, from being added multiple times.
```edge
@pushOnceTo('js')
@end
```
--------------------------------
### Render Markdown using @markdown Tag
Source: https://edgejs.dev/docs/edge-markdown
Render Markdown content by specifying a file path or raw content string using the @markdown tag.
```edge
@markdown({
file: absolutePathToMdFile,
})
@markdown({
content: contentAsString,
})
```
--------------------------------
### Alpine.js Map Component Initialization
Source: https://edgejs.dev/docs/components/provide_inject
This JavaScript code initializes an Alpine.js component named 'map'. It uses the Mapbox SDK to create a map instance, add markers with popups, and configure the map's initial center and zoom level based on provided data.
```javascript
document.addEventListener('alpine:init', () => {
window.Alpine.data('map', function (data) {
return {
createMap() {
mapboxgl.accessToken = ''
return new mapboxgl.Map({
container: this.$root,
style: 'mapbox://styles/mapbox/streets-v9',
center: data.center,
zoom: data.zoom
})
},
addMarker(map, markerData) {
const popup = new mapboxgl.Popup({ offset: 25 }).setText(markerData.label);
new mapboxgl.Marker().setLngLat([markerData.lon, markerData.lat]).setPopup(popup).addTo(map);
},
init() {
const map = this.createMap()
if (data.markers && Array.isArray(data.markers)) {
data.markers.forEach((marker) => {
this.addMarker(map, marker)
})
}
}
}
})
})
```
--------------------------------
### Test Custom Notification Tag in Action
Source: https://edgejs.dev/docs/creating-custom-tags
Demonstrates how to use the custom 'notification' tag by providing sample notification data and rendering a template that utilizes the tag. This verifies the conditional rendering and variable access.
```typescript
const notifications = {
success: 'Settings saved successfully'
}
const output = await edge.renderRaw(`
@notification('success')
{{ notification.message }}
@end
`, { notifications })
```
--------------------------------
### Validating @component calls
Source: https://edgejs.dev/docs/syntax_specification
Shows correct syntax for rendering components, including variations with and without options.
```edgejs
@!component('button')
```
```edgejs
@!component('button')
```
```edgejs
@!component
('button', {
type: 'primary'
})
```
```edgejs
@!component(
'button',
{
type: 'primary'
}
)
```
--------------------------------
### Access Markdown Rendered Properties with $markdown.render
Source: https://edgejs.dev/docs/edge-markdown
Access frontmatter, content, and table of contents by using the $markdown.render method.
```edge
@let(doc = await $markdown.render({
file: absolutePathToMdFile,
}))
{{{ doc.frontmatter.title }}}
{{{ doc.content }}}
{{{ doc.toc }}}
```
--------------------------------
### Output HTML with Overridden Prop
Source: https://edgejs.dev/docs/components/props
The resulting HTML after rendering a component where a prop was explicitly provided, overriding any default.
```html
```
--------------------------------
### Render Component Ignoring Default Styles
Source: https://edgejs.dev/docs/components/props
Demonstrates rendering a component with a prop set to ignore default styles, allowing custom classes to be applied.
```edge
@!input({
removeExistingStyles: true,
class: ['flex', 'mt-2', 'mb-4', 'border']
})
```
--------------------------------
### Convert AST to String with .stringify()
Source: https://edgejs.dev/docs/creating-custom-tags
Use the `.stringify()` method to convert a mutated Abstract Syntax Tree (AST) into a valid JavaScript expression. This is useful after transforming the AST.
```typescript
const reverse: TagContract = {
block: false,
seekable: true,
tagName: 'reverse',
compile(parser, buffer, token) {
const expression = parser.utils.transformAst(
parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
token.filename,
parser
)
console.log(parser.utils.stringify(expression)))
}
}
```
--------------------------------
### Generate Excerpt from HTML Content
Source: https://edgejs.dev/docs/helpers
Use the `excerpt` method to remove HTML tags, truncate text, and return plain text. It's ideal for creating summaries from HTML content.
```javascript
{{ excerpt( '
Hello, this is a dummy post
', 20 ) }}
```
--------------------------------
### Create Isolated Renderers with Locals
Source: https://edgejs.dev/docs/templates_state
Use `edge.createRenderer()` to create isolated instances of the Edge renderer. Share local data with each instance using the `.share()` method, ensuring data isolation between instances.
```javascript
const templ1 = edge.createRenderer()
const templ2 = edge.createRenderer()
templ1.share({
url: '/posts',
})
templ2.share({
url: '/posts/1',
})
await templ1.renderRaw('{{ url }}') // /posts
await templ2.renderRaw('{{ url }}') // /posts/1
```
--------------------------------
### Shiki Transformers for Code Blocks
Source: https://edgejs.dev/docs/edge-markdown
Utilize Shiki's built-in transformers for enhanced code block rendering, including diff markers, line highlighting, and word highlighting. These are enabled by default.
```typescript
```ts title=start/routes.ts
console.log('Highlighted') // [!code highlight]
console.log('Not highlighted')
console.log('hewwo') // [!code --]
console.log('hello') // [!code ++]
// [!code word:Hello]
const message = 'Hello World'
```
```
--------------------------------
### Evaluating JavaScript Expressions in Edge
Source: https://edgejs.dev/
Shows how to evaluate JavaScript expressions, including asynchronous operations like fetching data, within Edge templates.
```edge
@let(payments = await user.getPayments())
You have made {{ payments.length }} payments so far.
```
--------------------------------
### Parsing Front-Matter with $markdown.render
Source: https://edgejs.dev/docs/edge-markdown
Access extracted front-matter from Markdown files using the `frontmatter` property returned by `$markdown.render`. This includes properties like title and summary.
```edge
@let(doc = await $markdown.render({
file: absolutePathToMdFile
}))
{{ doc.frontmatter.title }}
{{ doc.frontmatter.summary }}
```
--------------------------------
### Lightweight Front-Matter Parsing with $markdown.frontmatter
Source: https://edgejs.dev/docs/edge-markdown
Efficiently parse only YAML front-matter without rendering Markdown content using `$markdown.frontmatter`. This method accepts a `file` or `content` property.
```edge
@let(meta = await $markdown.frontmatter({
file: absolutePathToMdFile
}))
{{ meta.title }}
{{ meta.summary }}
```
```edge
@let(meta = await $markdown.frontmatter({
content: rawMarkdownString
}))
```
--------------------------------
### Pretty-print values with inspect helper
Source: https://edgejs.dev/docs/debugging
Use the `inspect` helper to output a value in a readable HTML format. This is useful for inspecting complex data structures during development. View the output in a browser.
```edgejs
{{
inspect({
a: 1,
b: [3, 4, undefined, null],
c: undefined,
d: null,
e: {
regex: /^x/i,
buf: Buffer.from('abc'),
},
balance: BigInt(100),
id: Symbol('1234'),
scores: new Set([1, 2, 3]),
classes: new Map([['english', '1st'], ['maths', '2nd']]),
currentScores: new WeakSet([[1, 2, 3]]),
currentClasses: new WeakMap([[['english', '1st'], ['maths', '2nd']]]),
now: new Date()
})
}}
```
--------------------------------
### Merge Default Classes with Props
Source: https://edgejs.dev/docs/components/props
Assign default styling classes to an element using `$props.merge()` and combine them with any classes passed as props during component rendering.
```edge
```
--------------------------------
### Passing Data to Slots for Scoped Access
Source: https://edgejs.dev/docs/components/slots
This snippet demonstrates how a component can pass its state (e.g., 'sizes', 'cardSize') to its slots. This allows slot content to access and utilize data from the component's scope.
```edge
@let(cardSize = 'medium')
@let(sizes = {
medium: '350px',
small: '200px',
large: '450px'
})
{{{ await $slots.header({ sizes, cardSize }) }}}
{{{ await $slots.content({ sizes, cardSize }) }}}
```
--------------------------------
### Using Scoped Slots (Parent Access)
Source: https://edgejs.dev/docs/components/slots
This snippet shows how to use the card component where the slot content is defined in the parent and does not have access to the component's internal state. The comment indicates that 'cardSize' would be undefined within the slot.
```edge
@card()
@slot('header')
Quick start
@end
@slot('content')
{{-- The value of cardSize will be undefined --}}
I am a {{ cardSize }} card
@end
@end
```
--------------------------------
### Access Props using $props.get()
Source: https://edgejs.dev/docs/components/introduction
Alternatively, props can be accessed using the `$props.get()` method within the component.
```edge
{{ $props.get('type') }}
{{ $props.get('class') }}
{{ $props.get('text') }}
```
--------------------------------
### Include a Partial - EdgeJS
Source: https://edgejs.dev/docs/partials
Use the `@include` tag to insert a partial markup fragment into your template. The tag accepts the relative path to the partial file.
```html
@include('partials/header')
The main content goes here
@include('partials/footer')
```
--------------------------------
### Render Component Output
Source: https://edgejs.dev/docs/components/introduction
This is the rendered output of the form with two button components.
```html
```
--------------------------------
### Render Modal Component using Custom Tag
Source: https://edgejs.dev/docs/components/introduction
Render the modal component using its filename as a custom tag. Named slots are defined using the `@slot` directive.
```edge
@modal()
@slot('header')
Delete post
@end
@slot('content')
You are about to delete the post permanently
@end
@slot('footer')
@end
@end
```
--------------------------------
### Props API Changes
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
The `serialize` and `serializeExcept` methods have been replaced by `toAttrs`. Use the compatibility plugin to retain the old Props API.
```javascript
/**
* Serialize all attributes
*/
$props.serialize()
$props.toAttrs()
/**
* Serialize all except the mentioned attributes
*/
$props.serializeExcept(['text'])
$props.except(['text']).toAttrs()
/**
* Serialize only the mentioned attributes
*/
$props.serializeOnly(['class'])
$props.only(['class']).toAttrs()
/**
* Merge custom attributes
*/
$props.serializeOnly(['class'], { type: 'text' })
$props.only(['class']).merge({ type: 'text' }).toAttrs()
```
--------------------------------
### Pretty Print Values for Debugging
Source: https://edgejs.dev/docs/helpers
Utilize the `inspect` method to pretty print complex data structures for debugging purposes. The output is HTML, best viewed in a browser.
```javascript
{{ inspect({
a: 1,
b: [3, 4, undefined, null],
c: undefined,
d: null,
e: {
regex: /^x/i,
buf: Buffer.from('abc'),
},
balance: BigInt(100),
id: Symbol('1234'),
scores: new Set([1, 2, 3]),
classes: new Map([['english', '1st'], ['maths', '2nd']]),
currentScores: new WeakSet([[1, 2, 3]]),
currentClasses: new WeakMap([[['english', '1st'], ['maths', '2nd']]]),
now: new Date()
}) }}
```
--------------------------------
### Edge.js Template with Method Call
Source: https://edgejs.dev/docs/getting_started
An Edge.js template demonstrating the use of a method call on a variable within the template.
```edge
\n\n\n\n\t\n\n\n\n
\n Hello {{ username.toUpperCase() }}\n
\n\n\n
```
--------------------------------
### Disable Shiki and Use Custom Highlighter
Source: https://edgejs.dev/docs/edge-markdown
Disable Shiki's default highlighting and integrate your own rehype plugin for code highlighting. This allows for greater control over the highlighting process.
```javascript
edge.use(edgeMarkdown({
highlight: false,
rehypePlugins: [yourCustomCodePlugin]
}))
```
--------------------------------
### Generate AST for Tag Arguments
Source: https://edgejs.dev/docs/creating-custom-tags
Modify a custom tag's compile method to generate and log the Abstract Syntax Tree (AST) of its arguments. This allows for dynamic parsing and manipulation of tag inputs.
```javascript
const reverse: TagContract = {
block: false,
seekable: true,
tagName: 'reverse',
compile(parser, buffer, token) {
const expression = parser.utils.transformAst(
parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
token.filename,
parser
)
console.log(JSON.stringify(expression, null, 2))
}
}
```
--------------------------------
### Generate TOC with Custom Max Depth
Source: https://edgejs.dev/docs/edge-markdown
Configure the maximum heading depth for TOC generation via the toc configuration option within the $markdown.render method.
```edge
@let(doc = await $markdown.render({
file: absolutePathToMdFile,
toc: {
maxDepth: 2
}
}))
@end
```
--------------------------------
### Replacing @set Tag
Source: https://edgejs.dev/docs/changelog/upgrading-to-v6
The `@set` tag is removed in favor of `@let` for defining new variables and `@assign` for updating or mutating existing ones. Use the compatibility plugin to re-enable `@set`.
```edge
/**
* Define new variable
*/
@set('username', 'virk')
@let(username = 'virk')
/**
* Update existing variable
*/
@set('username', 'romain')
@assign(username = 'romain')
/**
* Mutate object properties
*/
@set(user, 'username', 'romain')
@assign(user.username = 'romain')
```
--------------------------------
### Implement Reverse Tag Logic
Source: https://edgejs.dev/docs/creating-custom-tags
Complete the implementation of a custom 'reverse' tag. This tag takes arguments, reverses their output value, and writes it to the buffer. It leverages AST manipulation and stringification.
```typescript
const reverse: TagContract = {
block: false,
seekable: true,
tagName: 'reverse',
compile(parser, buffer, token) {
const expression = parser.utils.transformAst(
parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename),
token.filename,
parser
)
const outputExpression = `${parser.utils.stringify(expression)}.split("").reverse().join("")`
buffer.outputExpression(outputExpression, token.filename, token.loc.start.line, false)
}
}
```
--------------------------------
### Render Raw Text as Template Synchronously with EdgeJS
Source: https://edgejs.dev/docs/getting_started
Use `renderRawSync` for synchronous rendering of raw text templates. This method is the synchronous counterpart to `renderRaw`.
```javascript
const template = `
Hello {{ username || 'Guest' }}!
`
edge.renderRawSync(template, { username: 'virk' })
```
--------------------------------
### Render SVG Icon with Custom Attributes
Source: https://edgejs.dev/docs/edge-iconify
Render an SVG icon with custom width, height, and color attributes.
```edge
@svg('heroicons:arrow-left-solid', {
width: 40,
height: 40,
color: 'purple'
})
```
--------------------------------
### Define a Modal Component
Source: https://edgejs.dev/docs/components/introduction
Define a modal component in `component/modal.edge` that uses named slots for header, main content, and footer.
```edge
```
--------------------------------
### Inline Edge Tags
Source: https://edgejs.dev/docs/syntax_specification
Inline tags like @include do not accept a body and do not need explicit closing statements.
```edge
@include('partials/some-file')
```
--------------------------------
### Test Custom Reverse Tag Implementation
Source: https://edgejs.dev/docs/creating-custom-tags
Test the custom 'reverse' tag with various inputs, including raw strings, variable references, and function calls. Ensure the output is correctly reversed.
```typescript
// With a raw string
assert.equal(await edge.renderRaw(`@reverse('virk')`), 'kriv')
// With variable reference
assert.equal(await edge.renderRaw(`@reverse(username)`, {
username: 'virk'
}), 'kriv')
// With function call
assert.equal(await edge.renderRaw(`@reverse(getUserName())`, {
getUserName() { return 'virk' }
}), 'kriv')
```
--------------------------------
### Chained @if, @elseif, and @else in Edge
Source: https://edgejs.dev/docs/conditionals
Chain multiple conditions using @elseif and provide a default case with @else. All conditional blocks must be closed with @end.
```edge
@if(user.fullName)
Hello {{ user.fullName }}!
@elseif(user.firstName)
Hello {{ user.firstName }}!
@else
Hello Guest!
@end
```
--------------------------------
### Define a Card Component with Named Slots
Source: https://edgejs.dev/docs/components/slots
This snippet shows how to define a reusable card component using named slots for 'header' and 'content'. Use this when your component needs distinct sections for content.
```edge
@let(attributes = $props
.merge({
class: ['card']
})
.toAttrs()
)
{{{ await $slots.header() }}}
{{{ await $slots.content() }}}
```
--------------------------------
### Define a Card Component with a Main Slot
Source: https://edgejs.dev/docs/components/slots
This snippet shows a card component that accepts a 'title' prop and uses the 'main' slot for its primary content. Use the main slot when a component primarily needs one block of content.
```edge