Using the Soonex template
2026-05-08
Clone corex-ui repos, run Mix and Tableau, tune themes, plus a Markdown gallery (tables, alerts, footnotes, images) matching MDEx in config.
This guide walks through cloning soonex, running the static site pipeline, renaming the OTP app, and tuning themes, color mode, and demo chrome. Further down, a Markdown feature gallery shows what MDEx emits for the extensions enabled in config/config.exs (table, tasklist, strikethrough, autolink, alerts, footnotes, and syntax_highlight: nil plus the Soonex code pipeline).
Get the code
The Tableau site lives in its own repository under the corex-ui organization.
Clone over HTTPS
git clone https://github.com/corex-ui/soonex.git cd soonex Clone over SSH
If you prefer SSH:
git clone git@github.com:corex-ui/soonex.git
Then cd into the repo directory you cloned.
Localized variant
For Gettext, Localize, and locale path prefixes, use soonex_i18n:
git clone https://github.com/corex-ui/soonex_i18n.git Work inside the Corex monorepo
If you develop from the monorepo checkout, use templates/soonex. The default is {:corex, "~> 0.1.0-beta.5"} from Hex; to build against a sibling corex repo, switch mix.exs to {:corex, path: "../../corex"} and run mix deps.get so deps/corex matches that checkout (the corex/hooks and corex/select style imports in assets/js/site.js stay the same).
First run
From the repository root, in order:
mix deps.getmix setupcd assets && npm install && cd ..mix assets.build- Either
mix tableau.buildfor a production tree under_site/, ormix tableau.serverfor the dev server with reload.
Rename the project
From the repo root, choose a snake_case OTP application name (lowercase letters, digits, underscores only). Commit or branch first, the rename task does not provide an undo.
mix project.rename acme What the rename task updates
lib/,config/,test/,priv/, andmix.exs- Selected
package.json/package-lock.jsonentries where applicable - Directory renames such as
lib/soonex/→lib/acme/, pluslib/soonex_web/→lib/acme_web/when that directory exists, and matchingtest/trees when present
After it finishes, run mix format and mix compile.
What you still edit by hand
Markdown under _posts/ and the root README are intentionally not rewritten so clone URLs like corex-ui/soonex stay accurate. Update branding copy yourself if you rebrand the app.
Permalinks and _posts/
Add or remove Markdown under _posts/ with a unique permalink per file (for example /docs/). Tableau emits one static tree per permalink.
Themes
Allowed theme ids and the default live in lib/soonex/theme.ex.
Import the matching priv/design/corex/theme/*.css files in assets/css/site.css so every [data-theme="…"] value you expose is present in the CSS graph.
Color mode (light / dark)
Light and dark preference is driven by data-mode on <html>, with helpers in lib/soonex/mode.ex and client logic under assets/js/mode.js.
Demo panel (Template Options)
The floating Template Options panel lives in lib/layouts/root/demo.ex. You can remove:
- the theme
<.select>block, - the mode
<.toggle_group>block,
or both.
Markdown feature gallery
The snippets below mirror MDEx options under config :tableau, :config, markdown: [mdex: …] and the Soonex post-processing step (Soonex.MDExConverter → Soonex.Markdown.CodeBlocks.transform/1) for fenced and inline code.
Headings
The post layout renders the post title as the page <h1>. In Markdown body text, ## maps to <h2>, ### to <h3>, and so on.
Third-level heading example
Fourth-level heading example
Emphasis, inline code, and strikethrough
Use bold, italic, combined emphasis, backticks for commands and paths, and strikethrough when extensions include strikethrough: true.
Links and autolink
Markdown link: Tableau on Hex. With autolink: true, bare URLs also become links, for example https://hexdocs.pm/mdex/MDEx.html.
Unordered and nested lists
- Clone the template
- HTTPS or SSH
- Optional monorepo path
- Run
mix setup - Build with
mix tableau.buildor serve withmix tableau.server
Ordered lists
- Edit
config/config.exsfor Tableau and asset tooling. - Add posts under
_posts/with a uniquepermalinkper file. - Ship
_site/to your host or CDN.
Task lists
tasklist: true renders GitHub-style checkboxes (inputs are disabled in static HTML):
- Enable MDEx extensions in config
- Replace demo copy with your product story
- Point the waitlist form at your backend
Table
Tables need extension: [table: true]:
| Topic | Where to look |
|---|---|
| Markdown pipeline | lib/soonex/md_ex_converter.ex, lib/soonex/markdown/code_blocks.ex |
| MDEx options | config/config.exs → markdown: [mdex: …] |
| Post layout | lib/layouts/post_layout.ex (.typo wraps body HTML) |
Blockquote
Blockquotes use the
.typo blockquotestyles: layer background, border, and italic body text for callouts that are not GitHub alerts.
Image
Site-root paths resolve after mix tableau.build (static files live under _site/):
GitHub-style alerts
With alerts: true, MDEx emits div.markdown-alert blocks. Titles come from the alert keyword.
Note
Use Note for neutral context that readers should notice.
Tip
Use Tip for shortcuts, conventions, or quality-of-life details.
Important
Use Important for security, data loss, or breaking-change warnings.
Warning
Use Warning when behavior may surprise operators.
Caution
Use Caution when the outcome depends on environment or ordering.
Footnotes
Footnotes need footnotes: true. References render as superscript links; definitions are collected at the end of the document1.
Fenced and inline code
Fenced blocks use the Soonex pipeline (Makeup + Corex Code + Clipboard when a language-… class is present):
defmodule Demo do @moduledoc "Shown in the gallery" def hello, do: :soonex end Inline highlighter: Mix.Task.run("tableau.build") and mix deps.get.
Raw HTML (render: [unsafe: true])
With unsafe: true, trusted HTML passes through MDEx. Use sparingly in content you control:
Example: native details / summary
Pair with Ctrl+B style keys using the .typo kbd styles.
Tip: After
mix tableau.build, open_site/docs/index.htmlto confirm exactly what shipped for this permalink.
See
Soonex.MDExConverter.convert/4andApplication.get_env(:tableau, :config)[:markdown][:mdex]for the exact option map passed toMDEx.to_html!/2. ↩