Skip to content

Tags

Tags are a syntactic extension of standard Markdown. You can use native Markdoc tags, like tables, conditionals, and partials, or create custom React components.

Similar to React components and HTML elements, tags are composable, and you can customize them with attributes.

{% if true %}

{% callout type="note" %}
Tags are composable!
{% /callout %}

{% else /%}

{% callout type="warning" %}
Tags aren't composable!
{% /callout %}

{% /if %}

Tags can be self-closing (similar to HTML). In this example, you'll see that the content body is removed, and that the tag is closed with a /.

{% image width=40 /%}

If your tag doesn't contain any new lines, then it's treated as an inline tag. Inline tags are automatically wrapped with a single paragraph Node (which renders a <p> element by default), to follow the CommonMark paragraph spec.

{% code %}

{% highlight %}Inline tag 1{% /highlight %}
{% highlight %}Inline tag 2{% /highlight %}

{% /code %}

Built-in tags

Markdoc comes out-of-the-box with four built-in tags: if, else, table, and partial.

If/Else

Dynamically render content when specific conditions are met using the {% if %} and {% else /%} tags. Markdoc uses conditionals with variables and functions.

Warning

Unlike JavaScript, Markdoc only considers undefined, null, and false to be falsey.

Use the if tag to render content when a condition evaluates to true.

This is shown no matter what.

{% if $myFunVar %}
Only appear if $myFunVar!
{% /if %}

Use the else tag to render alternate content when the if condition isn't met. You can use multiple else statements, and the final else tag triggers when none of the other conditions are met.

{% if $myFunVar %}
Only appear if $myFunVar!
{% else /%}
This appears if not $myFunVar!
{% /if %}

{% if $myFunVar %}
Only appear if $myFunVar!
{% else $otherFunVar /%}
This appears if not $myFunVar and $otherFunVar!
{% else /%}
This appears if not $myFunVar and not $otherFunVar
{% /if %}

Table

While Markdoc supports CommonMark tables, it also supports a list based syntax that allows for easy injection of rich content, like bulleted lists and code samples.

Basic table

A basic Markdoc table uses list syntax with each row separated by three dashes ---.

{% table %}
* Heading 1
* Heading 2
---
* Row 1 Cell 1
* Row 1 Cell 2
---
* Row 2 Cell 1
* Row 2 cell 2
{% /table %}

Table with rich content

Markdoc tables support rich text, including code samples and lists.

{% table %}
* Foo
* Bar
* Baz
---
*
  ```
  puts "Some code here."
  ```
*
  {% list type="checkmark" %}
  * Bulleted list in table
  * Second item in bulleted list
  {% /list %}
* Text in a table
---
*
  A "loose" list with

  multiple line items
* Test 2
* Test 3
---
* Test 1
* A cell that spans two columns {% colspan=2 %}
{% /table %}

Table without headings

{% table %}
---
* foo
* bar
---
* foo
* bar
{% /table %}

Set column and row span

Explicitly set column and row span.

{% table %}
---
* foo
* bar
---
* foo {% colspan=2 %}
{% /table %}

Text alignment

{% table %}
* Column 1 {% align="center" %}
* Column 2
* Column 3 {% align="right" %}
---
* foo
* bar
* baz
---
* foo
* bar {% align="right" %}
* baz
---
* foo {% align="center" %}
* bar
* baz
{% /table %}

Table caveats

Markdoc uses the table tag to locate places to parse the Markdown list syntax as a table, but it uses the table node to render the actual table elements. To customize how the default table renders, you need to register a custom a table node.

import { nodes } from '@markdoc/markdoc';

/** @type {import('@markdoc/markdoc').Config} */
const config = {
  nodes: {
    table: {
      ...nodes.table,
      render: 'Table' // your custom component goes here
    }
  }
};

Partial

Markdoc uses partials to reuse content across docs. The content is stored in a separate markdown file, and it's referenced from the file attribute in the partial tag, which includes the corresponding piece of content.

Here is an example of including the header.md file as a partial.

{% partial file="header.md" /%}

For more information on partials, check out the full partials docs.

Create a custom tag

To extend Markdoc with a custom tag, first, create a tag definition. In this example, you're creating a callout tag:

// ./schema/Callout.markdoc.js

export const callout = {
  render: 'Callout',
  children: ['paragraph', 'tag', 'list'],
  attributes: {
    type: {
      type: String,
      default: 'note',
      matches: ['caution', 'check', 'note', 'warning'],
      errorLevel: 'critical'
    },
    title: {
      type: String
    }
  }
};

Then, pass the tag definition to your config object:

import { callout } from './schema/Callout.markdoc';
import * as components from './components';

/** @type {import('@markdoc/markdoc').Config} */
const config = {
  tags: {
    callout
  }
};

const doc = `
# My first custom tag
`;

const ast = Markdoc.parse(doc);
const content = Markdoc.transform(ast, config);

const children = Markdoc.renderers.react(content, React, { components });

Next, pass your content to the Markdoc renderer. If you want to render a React component, specify which component should render this type of tag in the components mapping.

import * as React from 'react';
import { Icon } from './Icon';

function Callout({ title, icon, children }) {
  return (
    <div className="callout">
      <div className="content">
        <Icon icon={icon} />
        <div className="copy">
          <span className="title">{title}</span>
          <span>{children}</span>
        </div>
      </div>
    </div>
  );
}

return Markdoc.renderers.react(content, React, {
  components: {
    // The key here is the same string as `tag` in the previous step
    Callout: Callout
  }
});

Now you can use your custom tag in your Markdoc content.

{% callout title="Hey you!" icon="note" %}
I have a message for you
{% /callout %}
Information Circle
Hey you!

I have a message for you

Options

These are the optional fields you can use to customize your Tag:

OptionTypeDescription
renderstringName of the output (for example, HTML tag, React component name) to render
childrenstring[]Specifies which node types can be rendered as children of this tag. Used in schema validation.
attributes{ [string]: SchemaAttribute }Specifies which values (and their types) can be passed to this tag.
transform
(Ast.Node, ?Options) =>
  | RenderableTreeNode
  | RenderableTreeNode[]
  | null
Customize the Markdoc transform function for this tag, returning the custom output you want to eventually render. This is called during the transform step.
validate
(Node, ?Options) => ValidationError[];
Extend Markdoc validation. Used to validate that the content meets validation requirements. This is called during the validate step
selfClosingbooleanSpecifies whether a tag can contain children (false) or not (true). Used in schema validation.

Next steps


ParameterExpected value
nameSpecifies the display name for the connection.
codeDefines the unique identifier of the connection on the Zeenea platform. Once registered on the platform, this code must not be modified or the connection will be considered as new and the old one removed from the scanner.
connector_idThe type of connector to be used for the connection. The value must be looker and must not be modified.
enabledA boolean value to enable or disable the connection. The default value is true.
catalog_codeDefines the catalog code associated with the connection ("default" when empty).
secret_manager {
   enabled =
   key =
}

Configuration for a secret manager.

This configuration works only with Scanner version 73 or later and requires a functional secret manager configured in the scanner configuration file.

Where:

  • enabled: A boolean value to enable or disable the secret manager. The default value is true.
  • key: Specifies the name of the secret.
connection {
  tenant =
  oauth {
    client_id =
    client_secret =
  }
  timeout =
  fetch_offset_size =
}

Connection settings

Where:

  • tenant: The tenant address. In URL address, it is the name of your server before .cloud.looker.com.
  • client_id: Token name obtained within the Looker account menu.
  • client_secret: Token secret
  • timeout: (Optional) Customizable HTTP client timeout depending on Looker repository volume, in ms. The default value is 10000 (10 sec).
  • fetch_offset_size: (Optional) Customizable offset size for the dashboard inventory. The default value is 100.
lineage(Optional) A boolean value to activate the automatic lineage feature. The default value is true.
proxy {
  scheme =
  hostname =
  port =
  username =
  password =
}

Proxy configuration

Where:

  • scheme: Defines the proxy protocol (http or https).
  • hostname: Specifies the proxy address.
  • port: Sets the proxy port.
  • username: Provides the proxy username.
  • password: Provides the proxy account password.
tls {
  truststore {
    path =
    password =
    type =
  }
}

TLS Truststore settings

Where:

  • path: Specifies the TLS trust store file path. This file must be provided in case TLS encryption is activated (protocol https) and when certificates of Looker servers (or/and configured proxy) are delivered by a specific authority. It must contain the certification chain.
  • password: Provides the password of the trust store file.
  • type: Defines the type of the trust store file (PKCS12 or JKS). The default value is discovered from the file extension.

Operations

Operation nameAvailabilityDescriptionComment
itemOkQuery one item from the catalog, using a unique reference
itemBynameOkQuery one item from the catalog, using its name and type
itemsOkQuery a list of items of a given type from the catalogLimitations: Filters using "connections" or date type properties are not available yet.
nodeOkDirect query to a Node (to follow Relay conventions)
createContactOkCreate a contact
createItemOkCreate an item (all types EXCEPT contacts)
deleteContactOkDelete a contact
deleteItemOkDelete an item (all types EXCEPT contacts)Deleting Fields is limited to orphans.
updateContactOkUpdate a single contact
updateItemOkUpdate a single item (all types EXCEPT contacts)

Item Types

Item typeValueReadWrite
DatasetdatasetOkOk
FieldfieldOkOk
VisualizationvisualizationOkOk
Data processdata-processOkOk
ContactcontactOkOk
DatasourcedatasourceOkN/A
CategorycategoryOkOk
Custom Item TypeCode of the custom item as defined in Zeenea metamodelOkOk
Glossary Item TypeCode of the glossary item as defined in Zeenea metamodelOkOk

Basic Attributes

AttributeAvailable onItem type(s)ReadWriteDescriptionComment
idStringAny typeOkN/AZeenea internal identifier of the Item
keyStringAny typeOkOkForgeable unique identifier of the Itemkey = email for contacts
nameStringAny typeOkOkName of the Item in ZeeneaConcatenation of firstName and lastName for contacts
descriptionStringAny typeOkOkDescription of the Item in Zeenea
lastCatalogMetadataUpdateDateAny typeOkN/ADate of the last modification in Zeenea
typeStringAny typeOkN/AItem type value as defined above
completionNumberAny typeOkN/ACompletion rate of the documentation of the ItemNot implemented for contacts and data sources

Built-in Properties

PropertyAvailable onItem type(s)ReadWriteDescription
sourceNameStringDataset, Field, Visualization, Data ProcessOkN/AName of the item in the source system
sourceDescriptionStringDataset, Field, Visualization, Data ProcessOkN/ADescription of the item in the source system
lastSourceMetadataUpdateDateDataset, Field, Visualization, Data ProcessOkN/ALast time there was a change in the item metadata in the source system
orphanBooleanDataset, Field, VisualizationOkN/AItem is missing from the last inventory
deletionDateDateDataset, Field, Visualization, Data ProcessOkN/AThe date at which the item has been deleted in the source system
importDateDateDataset, Field, Visualization, Data ProcessOkN/AThe date at which the item has been imported into the catalog
fieldTypeStringFieldOkN/AThe normalized type of the field
fieldNativeTypeStringFieldOkN/AThe native type of the field as defined in the source system
canBeNullBooleanFieldOkN/AWhether the field is nullable
multivaluedBooleanFieldOkN/AWhether the field supports multiple values
primaryKeyBooleanFieldOkN/AWhether the field is a primary key
foreignKeyBooleanFieldOkN/AWhether the field is a foreign key
businessKeyBooleanFieldOkOkWhether the field is a business key
dataProfileEnabledBooleanFieldOkOkWhether the data profile on the field is enabled
dataProfilePublishedBooleanFieldOkOkWhether the data profile on the field is published
alternativeNames[String]All glossary typesOkOkList of alternatives names
emailStringContactOkOkEmail of the contact
firstNameStringContactOkOkFirst name of the contact
lastNameStringContactOkOkLast name of the contact
phoneStringContactOkOkPhone number of the contact

Connections

Source typeTarget type(s)Connection nameReadWriteDescription
datasetfieldfieldsOkN/AFields of a dataset
datasetdatasetrelationsOkOkDatasets linked through a foreign key
datasetdata-processingestersOkOkAll the data processes that have the dataset as input
datasetdata-processproducersOkOkAll the data processes that have the dataset as output
datasetvisualizationvisualizationOkOkFor the datasets that are embedded in a visualization, the visualization
datasetCustom item typeCode of the custom item typeOkOkCustom items of a given type linked to the dataset
datasetcategorycategoryOkOk(DEPRECATED) Category of the dataset
datasetcontactcuratorsOkOkCurators of the dataset
datasetcontactResponsibility nameOkOkContacts that have the given responsibility on the dataset
datasetdatasourcedatasourceOkN/AThe datasource of the dataset
datasetAll glossary item typesdefinitionsOkOkAll the glossary items linked to the dataset (can contain various types)
fielddatasetdatasetOkN/AThe dataset the field belongs to
fieldCustom item typeCode of the custom item typeOkOkCustom items of a given type linked to the field
fieldAll glossary item typesdefinitionsOkOkAll the glossary items linked to the field (can contain various types)
fieldcontactcuratorsOkOkCurators of the field
fieldcontactResponsibility nameOkOkContacts that have the given responsibility on the field
data-processdataset or Custom item typeinputsOkOkInputs of the data process
data-processdataset or Custom item typeoutputsOkOkOutputs of the data process
data-processCustom item typeCode of the custom item typeOkOkCustom items of a given type linked to the data process
data-processcontactcuratorsOkOkCurators of the data process
data-processcontactResponsibility nameOkOkContacts that have the given responsibility on the data process
data-processdatasourcedatasourceOkN/AThe datasource of the data process (if the data process has been harvested)
data-processAll glossary item typesdefinitionsOkOkAll the glossary items linked to the data process (can contain various types)
visualizationCustom item typeCode of the custom item typeOkOkCustom items of a given type linked to the data process
visualizationdatasetdatasetsOkOkDatasets embedded in the visualization
visualizationcontactcuratorsOkOkCurators of the data process
visualizationcontactResponsibility nameOkOkContacts that have the given responsibility on the visualization
visualizationdatasourcedatasourceOkN/AThe datasource of the visualization
visualizationAll glossary item typesdefinitionsOkOkAll the glossary items linked to the visualization (can contain various types)
Custom item typeAny typemembersOkOkAll the other items that are linked to this custom item
Custom item typedata-processingestersOkOkAll the data processes that have the custom item as input
Custom item typedata-processproducersOkOkAll the data processes that have the custom item as output
Custom item typecontactcuratorsOkOkCurators of the custom item
Custom item typecontactResponsibility nameOkOkContacts that have the given responsibility on the custom item
Custom item typeAll glossary item typedefinitionsOkOkAll the glossary items linked to the custom item (can contain various types)
Glossary item typeAny typeimplementationsOkOkAll the other items that are linked to the glossary item
Glossary item typeAll glossary item typeparentsOkOkParents of the glossary item in the glossary
Glossary item typeAll glossary item typechildrenOkOkChildren of the glossary item in the glossary
Glossary item typeAny typeimplementationsOkOkAll the other items that are linked to the glossary item
Glossary item typecontactcuratorsOkOkCurators of the glossary item
Glossary item typecontactResponsibility nameOkOkContacts that have the given responsibility on the glossary item
contactAny typecuratorOkOkAll the items the contact is curator of (various types)
contactAny typeResponsibility nameOkOkAll the items on which the contact has the given responsibility(various types)
datasourcedataset, field, visualization, data-processimportsOkN/AAll the items that have been imported from the source
categorydatasetmembersOkOk[DEPRECATED] Datasets of the category
categorycontactcuratorsOkOk[DEPRECATED] Curators of the custom item
categorycontactResponsibility nameOkOk[DEPRECATED] Contacts that have the given responsibility on the custom item
categoryAll glossary item typedefinitionsOkOk[DEPRECATED] All the glossary items linked to the category (can contain various types)

Custom Properties

Property typeReadWriteDescription
Template propertyOkOkAll properties associated to the template of an Item type in the Studio
Source propertyOkN/AAll properties harvested from a connector
Loading editor...