Slick Markdown Editor and Smart Text Parser for Craft CMS., (*1)
Features
Live Preview Support
Fast and consistent Github Flavored Markdown Parsing
Linkable Headers via named anchors
Reference Tags parsing
Extensible Shortcode parsing support
Event driven parsing API for developers
Advanced fenced code block parsing
Support for typography styles for better web typography
Emoji 🎉
Installation
You can install Doxter via the plugin store, or through Composer., (*2)
Craft Plugin Store
To install Doxter, navigate to the Plugin Store section of your Craft control panel, search for Doxter, and click the Try button., (*3)
Composer
You can also add the package to your project using Composer., (*4)
Open your terminal and go to your Craft project:, (*5)
cd /path/to/project
Then tell Composer to load the plugin:, (*6)
composer require verbb/doxter
In the Control Panel, go to Settings → Plugins and click the “Install” button for Doxter., (*7)
Markdown
You may already know that Craft ships with a markdown parser, which you can use in Twig like this:, (*8)
{% set markdownString = "# Craft can parse markdown text" %}
{{ markdownString | md }}
{# or #}
{{ markdownString | markdown }}
So, if all you want is to parse a markdown string or markdown content in a plain text field, you don’t need Doxter., (*9)
If, on the other hand, a lot of your content is going to be driven by markdown, read on., (*10)
Editor
The Doxter editor was designed to be used by developers and content editors alike. It attempts to make markdown more accessible to those who are less technical or haven’t written markdown before., (*11)
It also provides deep integration with Craft and the CP., (*12)
Parser
The Doxter parser is more than a parser, it’s actually a set of parsers that work together to provide an incredibly smart conversion., (*13)
Markdown is now a first-class citizen in Craft CMS, but beyond that, Doxter makes working with Code Blocks and Shortcodes a joy., (*14)
Typography
Here are a few of the styles that Doxter applies to your content:, (*15)
Straight quotes into “curly” quote HTML entities
Backtick style quotes into “curly” quote HTML entities
Dashes into en-dash and em-dash entities
Three consecutive dots into an ellipsis entity
French guillemets into true « guillemets » HTML entities.
Comma-style quotes into their curly equivalent.
Replace existing spaces with non-break where appropriate
Usage
To apply typography styles, make sure to enable addTypographyStyles from plugin settings page. That will tell Doxter to apply typography styles to all your content inside Doxter fields, when rendered., (*16)
Alternatively, see the following section on filters, (*17)
Filters
If the content you want to convert is not stored in a Doxter field, you can use one of the provided filters for on the fly conversion., (*18)
{% set markdownString = "# Better typography out of the box" %}
{{ markdownString | doxter( { addTypographyStyles: true ) }}
{% set plainText = "I'm in love with typography. --Selvin Ortiz" %}
{{ plainText | doxterTypography() }}
Shortcodes
Shortcodes are a first-class citizen in Doxter. You can simply tell Doxter what shortcode tags you want to process and by which templates they should be rendered. Doxter will then parse the source and hand your template a ShortcodeModel for each of the shortcode tags processed., (*19)
This means that in addition to advanced markdown parsing, shortcodes are supported in cases where highly specialized markup is required, you want to have full control of the output, and you need to give your content editors an easy way to embed content., (*20)
What are shortcodes?
A shortcode is a specific parsing rule that lets you do nifty things with very little effort. Shortcodes can embed videos and images or create output that would normally require lots of complicated, ugly code in just one line., (*21)
Inline vs Block
There are two types of shortcode tags you can use: Inline and Block., (*22)
Let’s start with an example of a block tag, a quote tag in this case:, (*23)
[quote author="Harold Abelson"]
Programs must be written for people to read, and only incidentally for machines to execute
[/quote]
<blockquote>
<p>
Programs must be written for people to read, and only incidentally for machines to execute<br>
-Harold Abelson
</p>
</blockquote>
Think of block tags as the equivalent to <divs>., (*24)
Now let’s take a look at an inline tag., (*25)
As an inline tag example, we’ll use an image shortcode tag., (*26)
Image Shortcode
This shortcode creates a fluid image from a plain image source URL or from an asset., (*27)
[image src=/path/to/img.jpg fluid/]
- or -
[image src={asset:123:url} fluid/]
We’re not even saving many key strokes. However, this is just a simple example to illustrate that you provide simple shortcodes that can be processed and transformed into beautiful, hand-crafted html once rendered by Doxter., (*28)
Video Shortcode
Here is another example; A shortcode that can be used to embed vimeo or youtube videos with ease., (*29)
Things get even more interesting when you couple the power of shortcodes, markdown, and reference tags. Here is an example [bio] shortcode that you could create by combining the above mentioned features of Doxter., (*30)
Bio Shortcode
[bio user={user:123}/]
John Smith, (*31)
@johnsmith, (*32)
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Add your own Shortcodes
To add new shortcodes, you simple create a file called doxter.php inside of your config directory and define a mapping of shortcode tag(s) to template. Templates should be given as paths relative to your templates directory., (*33)
Doxter gives you the flexibility to define code blocks in the standard way or fenced. If you fence your code blocks, you can also specify a language identifier. Additionally, you can tell Doxter exactly how to render your code blocks for easy integration with your syntax highlighter., (*34)
Standard Code Blocks
Standard code blocks are defined by one or more levels levels of indentation to denote where the code block begins/ends, (*35)
$greeting = 'Hello';
echo $greeting;
Fenced Code Blocks
Fenced code blocks use three or five backticks to denote where the code block begins/ends. You can also append a language identifier to the first set of backticks., (*36)
```php
$greeting = 'Hello';
echo $greeting;
```
Custom Block Template String
Since different syntax highlighters require slightly different markup in order to work, Doxter provides a way for you to define exactly how your code should be rendered. This is done by allowing you to define a code block template string that uses the placeholders {languageClass} and {sourceCode}., (*37)
Here are a few code block template string examples for the syntax highlighters I use most often. Prism is currently my favorite 👍, (*38)
A “bring your own html” flat structure to create links to important sections in your document, (*39)
How to use
Table of contents are currently part of the Doxter field API. That means that you won’t be able to take adventage of table of contents unless you’re using the Doxter Field., (*40)
To generate a table of contents for your document, use the toc method available in your Doxter field., (*41)
Here is a quick example of how you could use the generated table of contents for your sidebar., (*42)
{% set tableOfContents = entry.doxterFieldHandle.toc %}
{% set sidebarContent %}
No more stale links to other entries because someone changed the slug, (*46)
Reference tags are similar to shortcodes in that they are short snippets that return dynamic content. For reference tags, the content comes from Craft Elements such as users, entries, categories, etc., (*47)
The Craft docs for Reference Tags gives a pretty in-depth explanation of what they are and how to use them., (*48)
Doxter adheres to Craft’s parsing rules when processing reference tags and they get parsed before the markdown gets parsed, allowing for some pretty awesome functionality., (*49)
Linkable Headers
If you’re using Doxter to write documentation or long-form content, this is a must., (*50)
Having the ability to link directly a specific section within an article is very important for easy to navigate documentation., (*51)
This is what linkable headers do. , (*52)
For every header level you consider important, Doxter can make sure that it gets a named anchor so that you can link to it directly., (*53)
Parsing Options
Parsing option can be defined globally when defined in the plugin, per field, when the field is created or per call, when passed to a field method or the | doxter({}) filter., (*54)
Whether Doxter supported shortcodes should be parsed.
Filters
Not using the Doxter field? No problem., (*55)
When you install Doxter, you get two filters that you get to use without need to create a field to store your content first., (*56)
You can use these two filters (doxter and doxterTypography) on any variable or string in your templates., (*57)
Parsing Filter doxter
Doxter provides a filter that you can use to parse markdown in plain text fields or any other string that contains valid markdown, regardless of where it comes from., (*58)
Craft already provides a markdown filter that you can use it like this:, (*59)
{{ '# Markdown Rules' | markdown }}
You can also use the shorter version: | md., (*60)
However, Doxter goes beyond simple markdown parsing. It also provides support for Reference Tags, Linkable Headers, Shortcodes, and a few other hidden gems😉, (*61)
You can use the Doxter filter like this:, (*62)
{{ '# Doxter Rules' | doxter }}
Because Doxter does more than just parse markdown, you have the ability to pass in an options object., (*63)
If you want to get the benefit of advanced markdown parsing and also have a nice markdown field in the control panel, then the Doxter field is what you want., (*64)
Once you create a Doxter field and add it to your section, you’ll be able to get the rendered html like this:, (*65)
{{ entry.doxterFieldHandle }}
{# or #}
{{ entry.doxterFieldHandle.html }}
If you want to get back exactly what you typed into the editor without modification, you can use:, (*66)
Doxter is licensed under the MIT license, meaning it will always be free and open source – we love free stuff! If you'd like to show your support to the plugin regardless, Sponsor development., (*68)