See Pricing

Draft Layout Editor Guide

Draft Layout's Visual Editor is a WordPress plugin that allows you to build sites faster with Tailwind and HTML code, while letting clients edit those same styles in a visual drag-and-drop site builder.

This Technical Guide outlines how the Editor works and how to set up an optimal and efficient development workflow with it.

Installing the Plugin

After downloading the plugin's .zip file, go to your WordPress dashboard's "Plugins > Add Plugin > Upload Plugin" and select the ZIP file to upload.

After uploading and activating the plugin, enter your license key to register the site (see the "WP Dashboard > Draft Layout" menu).

It's also recommended to enable auto-updates so you always have the latest features and fixes.

Now you're ready to start coding, designing, and building!

If you're going to use AI to generate Tailwind HTML code, you can host your WordPress site on any external or cloud server.

But if you're a developer and you'll use a code editor (like VS Code), running a local dev installation on your computer will allow you to easily build the site's theme.

The WordPress Starter Theme

With most site builders, you use their drag-and-drop visual UI to design and build the site, including reusable components (headers, footers, navigation) and individual pages and posts.

But with Draft Layout, you'll build everything with code. And a WordPress theme is naturally the ideal place to put all this code.

Thankfully, you don't need to start from scratch. We provide a sample theme that you can use as a starter boilerplate/template, or build your own based on it:

Download the ZIP: https://github.com/UpperHorizon/draft-layout-theme/archive/refs/heads/main.zip

Or, clone the Git repo: https://github.com/UpperHorizon/draft-layout-theme

To install the theme, either:

Then activate the theme.

Visual Editor Interface

Go ahead and create a new page or post from the WordPress dashboard. When it opens in the Gutenberg/Block editor, save it as an empty draft. From the page/post list, you can also use the "Quick Edit" option to edit the title, slug, categories, tags, etc.

With the Draft Layout plugin activated, you should see an "Edit with Draft Layout" option when you hover over a page/post from the list.

Let's click that to open the empty page/post you just created inside Draft Layout's Visual Editor!

At the top left of the Editor UI, you can open the "Styles" panel for editing Tailwind styles and the "Insert" panel for inserting the reusable components you've created inside your theme files.

There's also a "Code Editor" panel that lets you edit and preview code changes directly inside the Editor.

Near the top center, there's a dropdown that lets you load up and edit all of the components and template files inside your theme.

At the top right, you can preview and save a page/post's content or draft. Also, open the "Outline" panel to see the structure/hierarchy of the content, where you can drag and drop as well.

Development Workflow

Finally, let's start writing some code!

To customize the theme and build your site, you'll need to edit the actual PHP files inside your theme.

If you're using AI-generated code, it's easier to use Draft Layout's built-in Code Editor; it'll allow you to paste or modify the code right inside the Editor UI.

For developers, you can use your favorite code editor to edit the theme's files directly.

When building your WordPress site and theme, you'll likely create template files for rendering various pages/posts.

You'll also create reusable component files for any block of code you want users to be able to easily add to a page from the Visual Editor.

So you can create components for:

To get started, use the dropdown at the top center of the Editor to select the "2 Column Layout" (components/2-column.php) component.

That component should load up, and you'll see a rendered preview of the code that's in the corresponding file.

Click the "Code Editor" icon to open that panel and you'll see the raw code of this component.

Try changing something here: the heading text, the .bg-orange-100 class, or anything else; then click the "Update" button. The Editor preview should update accordingly to reflect your changes.

If you're using your own code editor, then click the flask icon (top left of the Editor) to enable "Dev Mode", which will give you a live preview of the code from the file.

Now, you can open up the components/2-column.php file inside your code editor and make changes.

When you save that file, the live preview inside the Visual Editor should update to reflect that.

This is going to be your main workflow: use your favorite code editor or AI tool to write HTML/PHP code with Tailwind, while live previewing it inside the Editor to see what you're building.

Once you've made some changes, turn off Dev Mode (or close the Code Editor panel) and use the Visual Editor to see the Outline and how the HTML tags in your code map to the structure/hierarchy shown in the UI.

Click to select the different elements and see their styles in the "Styles" panel on the left. Notice how the Tailwind classes map to their respective UI editor input fields.

Try changing some of the styles here and click "Update" to save your changes.

Now, if you open up the "Code Editor" panel again or go back to your own code editor's components/2-column.php file, you'll see that the code (and Tailwind classes) has been updated to reflect those changes.

So you have a 2-way sync between your code editor and the Draft Layout Visual Editor:

The code you write is visually editable in the UI, and any changes you make in the drag-and-drop editor modify your code accordingly.

Once you've played around a bit and are happy with the changes, use the top center menu to go back to the empty page/post you were originally editing.

Now, use the "Insert" menu to add the "2 Column Layout" to the page. You can edit its styles further here as well.

Feel free to save and publish the page and see how it looks on the actual website.

Technical Architecture

CSS Handling

When you save a component/template from the Visual Editor, its code gets saved back to its respective PHP file in your theme.

At the same time, Draft Layout scans for all Tailwind classes inside your editable theme files, generates the CSS for them, and puts it inside tw-output.css.

Note: Draft Layout doesn't scan your theme files all the time. So if you use a new Tailwind class in your theme code, you have to toggle Dev Mode or re-save the file inside the WordPress Visual Editor for your tw-output.css to be updated with that new class.

You can make a duplicate copy of your theme to save as a WordPress child theme, so if anyone uses the Editor to make changes, the child theme's code gets updated while the main theme stays intact.

Having everything in code means it's also easy to version control with Git to track/diff changes, merge branches/PRs, and collaborate within a team.

For example, on the production server, you can set up a Git branch to track changes to your WP child theme.

Then, you can commit those changes and push them to your remote repository so your devs can pull those changes locally and merge them with their dev/prod branch to release theme updates.

When you use the Editor to save a page/post, Draft Layout pre-renders all the HTML and post-specific Tailwind CSS code (inside a <style> tag) and saves both inside the post_content of the post in the wp_posts table in your database.

This ensures lightning-fast performance: so when someone visits a page on your site, there's no pre-processing or rendering overhead from our Editor. In fact, our Editor does nothing while WordPress simply serves up the HTML stored in the database directly.

Draft Layout also utilizes standard PHP and WordPress capabilities and systems as much as possible, while keeping vendor-specific proprietary "magic" to a minimum to ensure that it integrates well with the wider WordPress ecosystem and plugins.

Theme File Structure

If you're interested, here are some technical details for developers; you can also give this guide to your AI tool so it understands the full context.

The Draft Layout Starter is a pretty typical classic PHP WordPress theme, with the main files being:

  1. style.css: Contains basic details about the theme. Feel free to change the theme's name or other things.

  2. tw-input.css: This is your input CSS file, which imports Tailwind and can contain an @theme {...} block for custom design tokens.

  3. tw-output.css: The generated Tailwind classes and CSS code are automatically placed in this file. You should enqueue this with wp_enqueue_style(). Don't put any of your own CSS here, as it'll be overridden. This file must exist.

  4. functions.php: It enqueues the tw-output.css stylesheet file and enables various theme features.

  5. header.php and footer.php: Contains typical WordPress theme header/footer code that can be used on every page of the site.

  6. single.php, page.php, and index.php: Typical WordPress templates for rendering individual/lists of posts and pages. They load the header/footer and use the WP query loop to output data.

  7. components/: Contains editable and reusable components. How you name these files and organize the folder structure is up to you.

Making Files Editable

To make a file (and its code) visually editable, you need to put a special PHP comment at the top containing JSON code:

<?php
/**
 * {
 * "dl-type": "component",
 * "name": "2 Column Layout",
 * "description": "A side-by-side 2-column layout section",
 * "category": "Sections"
 * }
 */
?>

Draft Layout will scan all .php files in your active theme for this JSON comment. The JSON object can specify these keys:

  1. dl-type: This is what defines the file as editable. The value can be either "component" for reusable blocks of code, or "template" for WordPress template files (like single.php, page.php, index.php, etc.). Both types are visually editable, but "template" files aren't shown in the "Insert" menu since they are not meant to be added to a page/post's content.

  2. name and description: A human-friendly name and description that's shown inside the visual editor.

  3. category: For Components, this category is used to sort and organize them for displaying in the visual editor.

For this JSON comment syntax to be recognized correctly, ensure that:

  1. You put the <?php tag at the very top of the file (first line), and either the very first or second comment contains the JSON object. The comment should only contain the JSON object, no other text.

  2. The comment needs to be a PHPDoc comment (not normal // Comment or /* Multiline */ ones), so it should start with /**, begin each line with *, and end with */.

  3. The JSON syntax needs to be valid: this means object keys and strings need to use double quotes, and the last item of an object/array can't have a trailing comma.

In the starter theme, you'll notice that most PHP files contain this JSON comment. Take a look at them and see how those details are mapped to and shown inside the visual editor UI.

Human-friendly PHP Previews

Inside template files (single.php, page.php), there's usually PHP code for rendering dynamic bits of data like the post's title, content, author, etc.

When editing these templates in the Visual Editor, it's helpful to show some sample preview text so users can understand what dynamic data there is and preview their styles as well.

To enable this, put a PHP comment that starts with dl-preview:, like this:

<h1>
  <?php /* dl-preview: Example Post Title */ echo esc_html(get_the_title()); ?>
</h1>

The above code dynamically renders the title of whatever post the user is viewing. But in the Visual Editor, it'll show up as a placeholder that says "Example Post Title".

For rendering dynamic images (like post thumbnails), you can use dl-preview: [img], which will show a grey box representing an image placeholder:

<?php /* dl-preview: [img] Post Thumbnail Image */ the_post_thumbnail('large'); ?>

Reusing Components

When you mark a PHP file as a "Component" (by including the { "dl-type": "component" } JSON comment), it'll show up in the "Insert" panel inside the Visual Editor.

Users can then click on it to add that to the current page/post's content they are editing. This allows you to reuse that same block of code.

But if you change the code/styles in the original file (either with the Visual Editor or any text/code editor), all the pages/posts that use that component won't automatically get updated.

If you want them to automatically render the latest version dynamically (like a "Global" component), you have 2 options:

First, if you're working with a WP template file (or a file imported by it), then you can execute PHP code and thus use WordPress's get_template_part() function, like this:

<?php get_template_part('components/header') ?>
<?php get_template_part('components/footer', null, ['variant' => 'full-width']) ?>

As you can see, you can also pass along your own arbitrary data in an associative array as the third argument (variant in this case), which you can then access inside that component (using $args['variant']).

Secondly, if you want to dynamically include a global component inside a page/post, the above approach doesn't work as you can't include PHP code inside the WP database's post_content.

For that, you'll need to use the shortcode [dl_comp]:

[dl_comp path="components/2-column"]

[dl_comp path="components/2-column" variant="full-width"]
  [dl_comp path="components/header"]
[/dl_comp]

You can simply type in this shortcode as text inside the Visual Editor. The only required argument is path, which specifies what theme file to dynamically import and render.

Any other arguments you include can be accessed inside the component's PHP with $args['...']. You can also nest shortcodes, with the nested content available as $args['content'].

Parsing Limitations

This is important: while you can put almost any HTML/PHP code inside your theme's files, and Draft Layout will make it editable, there are certain scenarios you need to be aware of.

Draft Layout needs to parse your HTML and PHP code to make them editable, and that works best when the HTML and PHP code tags/blocks are separate and don't break each other.

PHP tags nested inside valid HTML and inside attribute values are fine and should work:

<?php ... ?>

<div class="flex text-zinc-900 <?php echo join(' ', get_post_class()) ?>">
  <?php ... ?>
  
  <h1><?php echo get_the_title(); ?></h1>

  <a href="<?php ... ?>">Link</a>
</div>

However, don't break the HTML and invalidate the structure. Also, make sure there are no HTML tags inside PHP code (strings/comments). Avoid these examples:

<div <?php post_class() ?>>
  ...
</div>

<h1 <?php echo '>Heading</h1>' ?>

<?php the_title('<h1 class="page-title">', '</h1>'); ?>

In practice, this often means echoing the raw value from PHP (e.g., get_the_title() or get_post_class()) instead of mixing HTML and PHP (e.g., the_title('<h1>', '</h1>') or post_class()).

Lastly, don't leave HTML tags unclosed (e.g., open HTML tags without closing them in the same file). Ensure that the last PHP tag in a file is closed as well. Avoid:

<html>
  <body>

<?php
   ...